在C中读取字符串以防止出现问题的正确方法是什么

时间:2013-07-27 15:35:22

标签: c string input c-strings

我已经搜索了这个,但我真的找不到任何满足我的答案。因此,当字符串是控制台中的完整类型行时,我怀疑与C中的字符串输入有关。到现在为止,我习惯做这样的事情:

#include <stdio.h>
#include <stdlib.h>

int main() {

    int bar;
    char foo[30];

    scanf( "%d", &bar );

    fflush( stdin ); // prevent buffer "issue"
    gets( foo );
    fflush( stdin ); // I usually put this here too,
                     // but in most of times it is not
                     // necessary

    printf( "%d\n", bar );
    printf( "%s\n", foo );

    return 0;

}

但是阅读C++ Reference (gets),我意识到gets功能现已从C规范(2011)中删除。所以我搜索另一个表单做同样的事情,我在这里发现了一个帖子(我不记得链接,对不起),这样做的方法是使用fgets函数。所以,我的代码将是这样的:

#include <stdio.h>
#include <stdlib.h>

int main() {

    int bar;
    char foo[30];

    scanf( "%d", &bar );

    fflush( stdin );
    fgets( foo, sizeof foo, stdin );
    fflush( stdin );

    printf( "%d\n", bar );
    printf( "%s test\n", foo );

    return 0;

}

它的工作正常,一个细节。 fgets函数也会读取新行char,我不想这样做。让我们假设,如果我输入这个句子“一二”,程序的第一个版本将把它存储在c字符串中:

'o' | 'n' | 'e' | ' ' | 't' | 'w' | 'o' | '\0'

但第二个版本将存储此内容:

'o' | 'n' | 'e' | ' ' | 't' | 'w' | 'o' | '\n' | '\0'

我不想要这个,因为其中一个问题可能是字符串比较,因为我也需要将字符串与新行char进行比较,这将是一个问题,例如,在windows和linux之间,因为他们对新行使用不同的模式(\ r \ n和\ n分别为)。

所以,我的问题是:如何只使用标准函数读取c-string? 我怀疑是因为我是巴西联邦学院的老师,我从事入门编程学科的工作,我想要一些简单的工作,但有些学科使用C作为编程语言。当然,一种方法是更换新的行char,但我不能这样做!我需要一个简单的线来完成工作,没有惯用的结构。我与极端“低级”学生一起工作......

2 个答案:

答案 0 :(得分:1)

fflush(stdin);是未定义的行为,不要这样做。


否则,解决方案很简单:在fgets(buf, sizeof(buf), stdin)之后,用0-terminator替换换行符:

char *p;

p = strchr(buf, '\r');
if (p) *p = 0;

p = strchr(buf, '\n');
if (p) *p = 0;

答案 1 :(得分:0)

也许最好的方法是通过fgets

阅读
char line[BUFSIZ] = "";

while (line = fgets(line, sizeof line, stdin)) {
    size_t len = strlen(line); 
    /* Remove newline */ 
    if (line[len - 1] == '\n') {
        line[len - 1] = '\0'; 
    } 
    /* process line */
}