简体   繁体   English

为什么for循环永远不会结束?

[英]Why for loop never ends?

int ln;
printf("how many letters are your name?\n");
scanf("%d", &ln);
printf("Ok...enter your name by characters: \n");
char name[ln];
for (int i = 0; i<=ln; i++){
    scanf("%s", &name[i]);
}

This code should transform a name in the array but the for-loop never ends.此代码应转换数组中的名称,但 for 循环永远不会结束。 Someone who can help me?有人可以帮助我吗?

%s is scanning string so technically your whole name is considered as one element. %s 正在扫描字符串,因此从技术上讲,您的全名被视为一个元素。 So have to enter many strings.所以必须输入很多字符串。 just replace %s by %c and code should be ready to use只需将 %s 替换为 %c ,代码就可以使用了

Why for loop never ends?为什么for循环永远不会结束?

Inside the loop, scanf("%s", &name[i]);在循环内部, scanf("%s", &name[i]); attempts to read a name ln + 1 times, eventually attempting to save data outside name[] bounds.尝试读取名称ln + 1次,最终尝试将数据保存在name[]范围之外。

Saving data outside name[] bounds is undefined behavior (UB).name[]范围之外保存数据是未定义的行为(UB)。 Anything may happen.任何事情都可能发生。


Loop not needed to read one line of input as a name and name[] too small.循环不需要读取一行输入作为名称和name[]太小。

//char name[ln];
//for (int i = 0; i<=ln; i++){
//   scanf("%s", &name[i]);
//}

char name[ln+1];  // One more for a \0
if (scanf("%s", &name[i]) ==1) {
  Success();
}

Recommend to not use scanf() and use fgets() .建议不要使用scanf()并使用fgets()

char name[ln+1+1]; / One more for a \n and 1 for a \0
if (fgets(name, sizeof name, stdin)) {
  name[strcspn(name, "\n")] = '\0';  // lop off potential \n
  Success();
}

in the for condition, try to remove that equality and see, because you are allocating ln bytes in name variable, so the variable i will start from 0 and go to ln-1在 for 条件中,尝试删除该相等性并查看,因为您在 name 变量中分配 ln 字节,所以变量 i 将从 0 和 go 开始到 ln-1

for (int i = 0; i<ln; i++){
       scanf("%c", &name[i]);
   }

also note im using %c here to scan character, %s scans string.还要注意我在这里使用 %c 扫描字符,%s 扫描字符串。

Because your for loop must run one more time to end.因为您的 for 循环必须再运行一次才能结束。 simply change简单地改变

i<=ln

to

i<ln

" Why for loop never ends? " 为什么for循环永远不会结束?

First things first, I do not think that the loop is infinite.首先,我不认为循环是无限的。 For me it seems that you are just confusing %s with %c and interpret the waiting for more input as loop that "never ends".对我来说,您似乎只是将%s%c混淆了,并将等待更多输入解释为“永无止境”的循环。

You didn´t provided sufficient ressources to rebuild your issue, though.但是,您没有提供足够的资源来重建您的问题。

But let´s get started:但是让我们开始吧:

  1. The %s conversion specifier of scanf() is for reading a string, not a single character. scanf()%s转换说明符用于读取字符串,而不是单个字符。 If you want to read a single character per iteration, use scanf("%c", &name[i]);如果您想每次迭代读取一个字符,请使用scanf("%c", &name[i]); or name[i] = getchar();name[i] = getchar(); instead of scanf("%s", &name[i]);而不是scanf("%s", &name[i]); in the for loop.for循环中。

  2. Your loop condition i <= ln is faulty, as you attempt to write one character more than expected with it, because index counting starts at 0 , not 1 .您的循环条件i <= ln有问题,因为您尝试用它写比预期多一个字符,因为索引计数从0开始,而不是1 Use i < ln instead.请改用i < ln

  3. A string needs to have a terminating null character at the end.字符串末尾需要有一个终止 null 字符。 name needs to have one element more than to just hold the letters of the input name. name需要有一个元素,而不仅仅是保存输入名称的字母。 Also place name[ln] = '\0';还有地名name[ln] = '\0'; after the loop to insert a null character in the last element of VLA name .在循环之后在 VLA name的最后一个元素中插入一个 null 字符。


Note:笔记:

If you want to read a variable amount of characters from stdin which is determined at run-time, you don´t need to read each character separate and stop until the counter reaches ln - 1 .如果要从stdin中读取在运行时确定的可变数量的字符,则无需单独读取每个字符并停止直到计数器达到ln - 1

Reading a string with a variable amount of characters is one point, where fgets() is more appropriate than scanf() .读取具有可变数量字符的字符串是一点,其中fgets()scanf()更合适。

Use fgets (name, sizeof(name), stdin);使用fgets (name, sizeof(name), stdin); which ensures that the read string plus the string-terminating null character will fit exactly into name and catch the name once.这确保读取的字符串加上以字符串结尾的 null 字符将完全适合name并捕获该名称一次。

int ln;

printf("How many letters are in your name?\n");
scanf("%d", &ln);
getchar();              // catching left newline from scanf.

char name[ln + 1];      // +1 for null character.

printf("Ok...enter your name: \n");

fgets(name, sizeof(name), stdin);   // Will read the name and append the null character.

getchar();              // catching left newline from fgets. 
   

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM