这是家庭作业
我必须编写一个程序,要求用户输入一个字符串,然后我的程序会将输入字符串中的偶数和奇数值分开。这是我的计划。
#include <stdio.h>
#include <string.h>
int main(void) {
char *str[41];
char odd[21];
char even[21];
int i = 0;
int j = 0;
int k = 0;
printf("Enter a string (40 characters maximum): ");
scanf("%s", &str);
while (&str[i] < 41) {
if (i % 2 == 0) {
odd[j++] = *str[i];
} else {
even[k++] = *str[i];
}
i++;
}
printf("The even string is:%s\n ", even);
printf("The odd string is:%s\n ", odd);
return 0;
}
当我尝试编译我的程序时,我收到两个警告:
对于我的scanf
,我得到"format '%s' expects arguments of type char but argument has 'char * (*)[41]"
。我不确定这意味着什么,但我认为这是因为数组初始化。
在while
循环中,它给出了警告,指出指针和整数之间的比较。我不确定这意味着什么,我认为在C中进行比较是合法的。
当我编译程序时,我得到偶数和奇数字符串的随机字符。
任何帮助将不胜感激!
答案 0 :(得分:7)
这个声明是错误的:
char *str[41];
你宣布41个未初始化的字符串。你想要:
char str[41];
然后,scanf("%40s" , str);
,没有&
并限制输入大小(安全)
然后是循环(你的while (str[i]<41)
错误,它可能会立即结束,因为字母从65开始(ascii代码为“A”)。你想测试i
对41但是测试{ {1}}反对str[i]
,否则你会在\0
或odd
字符串之一的nul-termination char之后得到所有垃圾(如果字符串不是40字节长)
even
如果你想使用指针(分配要求),只需像以前一样定义while (str[i]) {
if (i % 2 == 0) {
odd[j++] = str[i];
} else {
even[k++] = str[i];
}
i++;
}
:
str
如上所示扫描其上的输入值,然后指向它:
char str[41];
现在您在缓冲区上定义了一个指针,如果您需要使用deference而不是索引访问,则可以执行以下操作:
char *p = str;
(我们必须为偶数/奇数测试增加while (*p) { // test end of string termination
if (i % 2 == 0) { // if ((p-str) % 2 == 0) { would allow to get rid of i
odd[j++] = *p;
} else {
even[k++] = *p;
}
p++;
i++;
}
,否则我们必须测试i
均匀度
aaaand最后一个经典错误(感谢最后一刻的评论),p-str
&amp; even
不会被终止,因此在打印它们时最终会产生垃圾的风险,您需要:
odd
(如another answer所述,检查偶数和奇数的概念,预期结果可能是相反的方式)
答案 1 :(得分:3)
您的代码中存在多个问题:
char *str[41]
,而不是char
数组。scanf
而不是它的地址:当传递给函数时,数组会衰减成指向其第一个元素的指针。scanf
读取的字符数。(&str[i] < 41)
将i
元素的地址与值41
进行比较,这毫无意义。字符串的结尾是空终止符,可以使用(str[i] != '\0')
进行测试。str
来阅读str[i]
中的字符。even
和odd
数组。以下是修改后的版本:
#include <stdio.h>
int main(void) {
char str[41];
char odd[21];
char even[21];
int i = 0;
int j = 0;
int k = 0;
printf("Enter a string (40 characters maximum): ");
if (scanf("%40s", str) != 1)
return 1;
while (str[i] != '\0') {
if (i % 2 == 0) {
odd[j++] = str[i];
} else {
even[k++] = str[i];
}
i++;
}
odd[j] = even[k] = '\0';
printf("The even string is: %s\n", even);
printf("The odd string is: %s\n", odd);
return 0;
}
请注意,您对偶数和奇数字符的解释假定基于1的偏移,即:第一个字符是奇数字符。这与C方法不一致,其中偶数字符将被解释为从字符串的开头开始均匀偏移,从0开始。
答案 2 :(得分:2)
这是你的解决方案:)
#include <stdio.h>
#include <string.h>
int main(void)
{
char str[41];
char odd[21];
char even[21];
int i = 0;
int j = 0;
int k = 0;
printf("Enter a string (40 characters maximum): ");
scanf("%s" , str);
while (i < strlen(str))
{
if (i % 2 == 0) {
odd[j++] = str[i];
} else {
even[k++] = str[i];
}
i++;
}
odd[j] = '\0';
even[k] = '\0';
printf("The even string is:%s\n " , even);
printf("The odd string is:%s\n " , odd);
return 0;
}
解决了声明中的错误,扫描字符串值,while循环的条件以及数组元素的赋值。 :)
答案 3 :(得分:2)
许多答案都准备好指出原始代码的问题。
以下是一些减少内存使用量的建议,因为2个阵列odd[], even[]
不是需要。
作为&#34;偶数&#34;看到字符,打印出来。
作为&#34;奇怪&#34;看到字符,将它们移动到数组的第一部分。
替代打印:如果代码使用"%.*s"
,则数组不需要空字符终止。
#include <stdio.h>
#include <string.h>
int main(void) {
char str[41];
printf("Enter a string (40 characters maximum): ");
fflush(stdout);
if (scanf("%40s", str) == 1) {
int i;
printf("The even string is:");
for (i = 0; str[i]; i++) {
if (i % 2 == 0) {
str[i / 2] = str[i]; // copy character to an earlier part of `str[]`
} else {
putchar(str[i]);
}
}
printf("\n");
printf("The odd string is:%.*s\n ", (i + 1) / 2, str);
}
return 0;
}
或只是
printf("The even string is:");
for (int i = 0; str[i]; i++) {
if (i % 2 != 0) {
putchar(str[i]);
}
}
printf("\n");
printf("The odd string is:");
for (int i = 0; str[i]; i++) {
if (i % 2 == 0) {
putchar(str[i]);
}
}
printf("\n");