【问题标题】:strncpy() segmentation fault (again)strncpy() 分段错误(再次)
【发布时间】:2014-04-25 03:40:50
【问题描述】:

我正在尝试编写一个文字格式化程序,该程序接受一个数据文件,并对其进行格式化,以便每行最多有一定数量的字符。当我尝试遍历文件每一行中的单词时遇到分段错误错误。

int readFile(  )
{
    int rc = 1;
    char readBuffer[ 256 ];
    char writeLine[ 256 ];
    char *word = malloc( numChars * sizeof( char ) );
    
    writeFile = fopen( writeName, "a" );
    
    if ( ( openFile = fopen( readName, "r" ) ) == NULL ) 
    {
        printf( "Unable to open %s file for read\n", readName );
        rc = 0;
    } 
    else 
    {       
        while( fgets( readBuffer, sizeof( readBuffer ), openFile) != NULL ) 
        {
            strncpy( writeLine, "", 0 );
            if ( readBuffer[0] != EOF ) 
            {
                strncpy( word, strtok( readBuffer, " " ), numChars -1 );
                while( word != NULL )
                {
                    if( strlen( word ) + strlen( writeLine ) < numChars )
                    {   
                        strcat( writeLine, word );

我在这里得到错误:

                        strncpy( word, strtok( NULL, " " ), numChars -1 );
                    }
                    else
                    {
                        fprintf( writeFile, "%s", writeLine );
                        strcpy( writeLine, word );
                        strncpy( word, strtok( NULL, " " ), numChars -1 );
                    }
                }
            }
        }
    }
    
    return rc;
}

我不明白为什么会这样。 strncpy 的重点不是告诉它要复制多少个字符吗?如果我明确告诉它只将字符复制到字符串长度以下一个,为什么会出现分段错误? 编辑:我已将代码修改为以下内容:

            strcpy( writeLine, strtok( readBuffer, " " ) );
            
            while( strcpy( word, strtok( NULL, " " ) ) != NULL )
            {
                if( strlen( word ) + strlen( writeLine ) < numChars )
                {   
                    strcat( writeLine, word );
                }
                else
                {
                    fprintf( writeFile, "%s", writeLine );
                    strcpy( writeLine, word );
                }
            }

这不会改变操作,它仍然是分段错误。如何检查令牌是否有效并且如果有效仍访问相同的令牌?


已解决

我开发了一个可行的解决方案:

    writeLine[0] = '\0';
    
    while( fgets( readBuffer, sizeof( readBuffer ), openFile) != NULL ) 
    {
        if ( readBuffer[0] != EOF ) 
        {               
            for( word = readBuffer; NULL != ( word = strtok( word, " \t\n" ) ); word=NULL )
            {
                printf("%s\n", writeLine );
                if( strlen( word ) + strlen( writeLine ) < numChars )
                {   
                    strcat( writeLine, word );
                    strcat( writeLine, " " );
                }
                else
                {
                    printf("%s", "print\n");
                    fprintf( writeFile, "%s\n", writeLine );
                    strcpy( writeLine, word );
                    strcat( writeLine, " " );
                }
            }
        }
    }
    fprintf( writeFile, "%s\n", writeLine );

【问题讨论】:

  • strtok 返回 NULL
  • 你能解释一下为什么它会返回 NULL 以及可以做些什么来解决它?
  • strtok 在到达缓冲区末尾时返回 NULL。您需要在传递 strncpy 之前检查它的返回值。此外,您的 while 循环是错误的,因为 word 永远不会为 NULL。您的循环应该循环直到 strtok 的返回值为 NULL。
  • strncpy( writeLine, "", 0 ); 应该完成什么?它似乎什么也没做。
  • @shf301,那我会做类似 while(word = strtok...) 的事情吗? chux,我将 writeLine 设置为空,所以我可以用循环附加到它上面。

标签: c segmentation-fault strncpy


【解决方案1】:

strncpy() 不会在达到限制字符数时终止。您需要自己终止。这使得声明 strncpy( writeline, "", 0 ); 什么都不做(甚至不终止字符串)。然后你添加到那个未初始化的字符串上,它会很糟糕。

【讨论】:

    【解决方案2】:

    strncpy 的重点不是告诉它要复制多少个字符吗?

    没有。关键是你告诉它你有多大的缓冲区可用。然后它将尽可能多的字符复制到该缓冲区中(将其余字符归零),并且如果可用字符数至少与缓冲区大小一样多,它不会以空值终止。

    我个人从不使用它;实际上总是生成字符串的替代方案包括 strcpysprintfsnprintfmemcpy,以及手动附加空终止符。

    始终建议阅读标准函数的文档。 strncpy( writeline, "", 0 ); 什么都不做。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-05
      • 1970-01-01
      相关资源
      最近更新 更多