【问题标题】:Loop closes unexpectedly循环意外关闭
【发布时间】:2017-12-14 15:39:53
【问题描述】:

我检查了这个,但没有帮助 - For loop scans one less time in c 所以,我是编程新手,我试图从 SPOJ 解决这个问题(我的疑问很普遍,因此没有在 SPOJ 论坛上发布)。 http://www.spoj.com/problems/STRHH 我使用 GCC 在 CodeBlocks 中制作并运行了这段代码,它按预期运行,但当我通过 Ideone 运行它时运行方式不同。

#include<stdio.h>
#include<malloc.h>
#include<string.h>
int main()
{
    int n,i,length,j;
    char **ptrarray; //creating a pointer array that holds addresses of the strings  
    fscanf(stdin,"%d",&n);
    ptrarray = (int *)malloc(n*sizeof(int)); //dynamically allocating memory for 'n' strings and storing their addresses in 'ptrarray'
    for (i=0;i<=n;i++)
        ptrarray[i] = (char *)malloc(201); //dynamically allocating memory for the strings
    for (i=0;i<=n;i++)
        fgets(ptrarray[i],201,stdin); //receiving string
    for (i=0;i<=n;i++)
    {
        length=strlen(ptrarray[i])-1; //string length
        for (j=0;j<(length)/2;j+=2) //obtain every other character up to half of the string length
            printf("%c",ptrarray[i][j]);
        printf("\n");
    }
    return 0;
}

输入:

4
your 
progress 
is 
noticeable

预期输出:

y
po
i
ntc

所以,当我在 Codeblocks 中运行它时,我得到了预期的输出,但在 ideone 上运行它(并在 SPOJ 上提交)时,printf 循环只运行三次而不是 4 次,我得到的输出是:

y
po
i

我的问题是为什么我没有在 ideone 中获得第四个“ntc”,为什么它不被接受?

编辑:将“200”字节更改为“201”字节,使用 fscanf 代替 scanf,删除 fflush 并更新循环条件。 所以,如果我从 ' 更改循环条件,我会得到所需的答案

【问题讨论】:

  • 调用fflush(stdin); 是未定义的行为。不要那样做。
  • 一个 200 个字符的字符串需要 201 个字符的存储空间(一个额外的用于字符串终止符)。
  • @KlasLindbäck,看不出有什么问题:fgets 读取“直到读取的字符数等于 n - 1”,
  • 我对@9​​87654329@ 和ptrarray = (int *)malloc(n*sizeof(int)) 感到困惑。
  • length=strlen(ptrarray[i])-1; //half of the string 确定不是字符串的一半长度

标签: c loops


【解决方案1】:

这个:

char **ptrarray; //creating a pointer array that holds addresses of the strings  
scanf("%d",&n);
ptrarray = (int *)malloc(n*sizeof(int)); //dynamically allocating memory for 'n' strings and storing their addresses in 'ptrarray'

没有意义;您正在为 n 整数分配空间,但将结果分配给指向指针的指针(通常,两者的大小都与整数相同)。

分配应该是:

ptrarray = malloc(n * sizeof *ptrarray);

这将分配n 乘以ptrarray 指向的大小,即sizeof (char *),但不会重复任何类型名称。

这是一个相当通用且安全得多的模式,值得学习。

正如评论中提到的,不要fflush(stdin);,这是未定义的行为。

【讨论】:

  • 补充说明,ptrarray 不是数组,应该用正确的名称重命名。
  • @unwind sizeof *ptrarray 等价于 sizeof char * 对吧? char * 是指向字符的指针。所以它将保存一个无符号整数。按照这个逻辑,sizeof(int) 与 sizeof(char *) 和扩展 sizeof(*ptrarray) 不一样吗?
  • @NaishadhVora “而 char * 是一个指向字符的指针。因此它将包含一个无符号整数。” --> 否。指针大小和int 大小不相关。
  • @chux 我被告知 char * 将保存一个字符的地址。那不是无符号整数的形式吗?抱歉,我对此很陌生!
  • @NaishadhVora "char * 将包含一个字符的地址" 是的,这是真的。 “那不是无符号整数的形式吗?”也许,也许不是——这是一个实现细节。更重要的是:代码不应该关心这些。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-30
  • 2014-05-06
  • 1970-01-01
  • 2015-12-26
相关资源
最近更新 更多