除非我的电脑疯了或者我错过了什么。当我运行代码时,变量计数在每个内部while循环后不会重置为零。
防爆。如果我输入:
XXX
YYYY
计数输出为1-9。但它应该是1-4和1-5。
int main(){
char string[500][500];
int letterWords[15]={0};
printf("Enter several lines of text.\n");
scanf("%[^\t]", string);
int a=0, b=0;
int count=0, i;
while(string[a][0]!='\0'){
while(string[a][b]!='\0'){
count++;
b++;
printf("%d\n", count);
}
printf("\n");
count-=2;
letterWords[count]++;
a++;
b=0;
count=0; //the count doesn't reset to 0 for some reason
}
for(i=0;i<15;i++){
if(letterWords[i]==0){
continue;
}
printf("%d %d\n", i+1, letterWords[i]);
}
}
答案 0 :(得分:0)
与您的想法不同,scanf
仅扫描string[0]
中的行。
其他人没有初始化。试图阅读它们是未定义的行为。
现在再次在string
中传递scanf
有一件事。价值方面,它包含相同的
价值与string[0]
的价值相同。所以它基本上读取string[0]
中的行。
假设scanf
现在没有失败,你进入了while循环。
第一次检查是多余的。当a
不是0
时,它将调用未定义的行为。
通过增加count
来计算长度。令人惊讶的是,你试图在letterWords
中增加价值。
当值count
不是<=14
时,您再次访问数组索引超出范围。这也是未定义的行为。
现在经过这么多未定义的行为之后,count=0
的通常任务被压制了。
只是程序抱怨,然后行甚至不执行。(也许)。
为了获得多行,请使用fgets
并阅读在不同\n
- s中分隔的每一行(string[i]
)。
然后根据读取的行数运行循环。一切都会好起来的。
while(string[a][0]!='\0')
并不是一种好的方式,而是根据行读数进行检查。(在您的情况下)
同样printf("%s",string[i])
将打印每一行。
使用scanf()
的更好方法是检查scanf()
的返回值。
答案 1 :(得分:0)
我冒昧地重塑代码(否则会改变很多东西)
int main() {
char string[500][500];
int letterWords[15]={0}; // max line length is 14
int a,i,count;
printf("Enter several lines of text (end with ^D).\n");
for(a=0 ; a < 500 && fgets(string[a], 500, stdin) ; a++) /* nothing */;
for(i=0 ; i<a ; i++) {
for(count=0 ; string[i][count] && string[i][count] != '\n' ; count++) /* nothing */ ;
printf("Line %d: %d\n", i, count);
letterWords[count]++;
}
for(i=0 ; i<15 ; i++) {
if(letterWords[i]) {
printf("%d %d\n", i, letterWords[i]);
}
}
return 0;
}
说明:
for(a=0 ; a < 500 && fgets(string[a], 500, stdin) ; a++) /* nothing */;
使用fgets
读取给定最大长度的行。行计数器为a
要完成输入,用户在空行处按 Control-D (EOF
)。
当fgets
满足(或发生错误)时,NULL
会返回EOF
。
for(i=0 ; i<a ; i++) {
i
是strings
中的索引,从0
到a-1
。
for(count=0 ; string[i][count] && string[i][count] != '\n' ; count++) /* nothing */ ;
不需要其他变量。 count
计算该行中的字符数,并在符合\n
或\0
时停止。
printf("Line %d: %d\n", i, count);
letterWords[count]++; // Increment the line-counter
}
请注意,任何行都不应超过14个字符。最后,
for(i=0 ; i<15 ; i++) {
if(letterWords[i]) {
printf("%d %d\n", i, letterWords[i]);
}
}
打印结果Length Number_of_lines_of_that_length
。
答案 2 :(得分:0)
读取输入行时,请使用面向行的输入函数,例如fgets
或POSIX getline
。 scanf
充满了陷阱,等待新的C程序员陷入其中。
虽然您的代码(尤其是linewords
)有点难以理解,但您尝试捕获其中的长度以打印带有字符的所有行。
你必须要理解的一件事是将一个scanf
放在首位 - 只读一个输入。这使得你的嵌套循环在徒劳无功中付出了巨大的努力。相反,您需要在外循环中移动读取,这样您就可以在每个循环中读取一行输入(技术术语)。
不是使用嵌套循环,只需使用单个循环循环不断获取用户输入,直到用户生成EOF
( Ctrl + d 或 Ctrl + z 在windoze上)。在那里,您只需验证读取(字符串实际上适合您的分配存储)并修剪尾随的\n'
读取并通过面向行的输入函数包含在缓冲区中。
虽然您可以自由地将每个字符串的长度存储在一个单独的数组中,但对于本练习,只需调用strlen
即可。
完全放弃,您可以执行以下操作:
#include <stdio.h>
#include <string.h>
#define MAX 500 /* if you need constants, define them */
int main () {
int n = 0; /* strings index */
char string[MAX][MAX] = { "" }; /* 2d array of char */
printf ("\nenter several lines of text\n"
"[ctrl+d (ctrl+z on windows) when done]\n\n");
for (; n < MAX;) { /* take input until n == MAX or user EOF */
printf ("line[%2d]: ", n); /* prompt for input */
if (fgets (string[n], MAX, stdin)) { /* read line */
size_t len = strlen (string[n]); /* get length */
if (len && string[n][len - 1] == '\n') /* check last char '\n' */
string[n][--len] = 0; /* overwrite with nul-terminating char */
else { /* line too long handle error */
fprintf (stderr, "error: line too long '%d'.\n", n);
return 1;
}
n++; /* increment line index */
}
else { /* handle EOF */
printf ("\nall done!\n\n");
break;
}
}
for (int i = 0; i < n; i++) /* output each line read */
printf ("string[%2d] (%3zu chars) : '%s'\n",
i, strlen (string[i]), string[i]);
return 0;
}
(注意:如果您的目标是跳过零长度字符串,那么只需在最终if (strlen(string[i]))
之前添加printf
检查即可。(您可以将它保存在最终循环中的变量中以防止调用它两次))
示例使用/输出
$ ./bin/rdstrings2d
enter several lines of text
[ctrl+d (ctrl+z on windows) when done]
line[ 0]: my dog
line[ 1]: has fleas
line[ 2]: my cat is lucky, and
line[ 3]: has none
line[ 4]:
all done!
string[ 0] ( 6 chars) : 'my dog'
string[ 1] ( 9 chars) : 'has fleas'
string[ 2] ( 20 chars) : 'my cat is lucky, and'
string[ 3] ( 8 chars) : 'has none'
答案 3 :(得分:0)
//尝试使用此代码,这似乎可以正常工作 的#include
int main(){
char string[500];
int letterWords[15]={0};
printf("Enter several lines of text.\n");
scanf("%[^\t]", string);
int a=0, b=0;
//printf("%s",string);
int count=0, i;
while(string[a]!='\0'){
while(string[a]!='\n'){
count++;
a++;
printf("%d\n", count);
}
printf("\n");
count-=1;
letterWords[count]++;
a++;
b=0;
count=0; //the count doesn't reset to 0 for some reason
}
for(i=0;i<15;i++){
if(letterWords[i]==0){
continue;
}
printf("%d %d\n", i+1, letterWords[i]);
}
}