在 C 中迭代来自标准输入的字符串

Iterating through a string from stdin in C

我想读入 stdin 的前 20 个字符。我可以只使用迭代 20 次的 for 循环和 scanf("%c",&var) 吗?如果输入的长度少于 20 个字符会怎样?

我正在考虑使用 gets() 来绕过这个问题。读入整行,然后遍历字符串,直到计数器达到 20 或到达字符串末尾。但是,有没有办法检测字符串的结尾?

或者有更好的方法吗?

之所以问这个,是因为我们不允许使用 string.h 库中的任何函数。

你可以这样试试...

1 - 使用 scanf() 读取一行的前 20 个字符,如下面的字符数组示例所示。

例如:

  char str[21];

  scanf("%20[^\n]s",str);

2 - 最后,您的字符数组中将包含 line 的前 20 个字符。

3 - 如果行长度小于 20 那么它会自动在行尾分配 '\0' 字符。

并且如果您想查找数组中的字符总数,则计算数组的长度

**字符串的结尾由'\0' NULL字符决定

这是一个使用基本 fgetc 的解决方案:

#include <stdio.h>

#define LEN(arr) ((int) (sizeof (arr) / sizeof (arr)[0]))

static void ReadLine(FILE *file, char result[], int resultLen)
{
    int i, ch;

    ch = fgetc(file);
    i = 0;
    while ((ch != EOF) && (ch != '\n') && (i < resultLen - 1)) {
        result[i] = ch;
        ch = fgetc(file);
        i++;
    }
    result[i] = '[=10=]';
}


int main(void)
{
    char s[20 + 1];

    ReadLine(stdin, s, LEN(s));
    puts(s);
    return 0;
}

这是一个简短的版本,它使用 scanf:

#include <stdio.h>

int main(void) {
    char buffer[20 + 1] ; // 20 characters + 1 for '[=10=]'
    int  nread ;
    nread = scanf("%20[^\n]", buffer) ; // Read at most 20 characters
    printf("%s\n", buffer);
    return 0;
}

scanf 会自动在 buffer 的正确位置添加 '[=15=]' 字符,而 "%20[^\n]" 最多显示 '\n'.

不同的 20 个字符

如果你想把它放在一个函数中并避免重复20(容易出错):

#include <stdio.h>

int read_chars (char buffer[], int len) {
    char format[50] ;
    sprintf(format, "%%%d[^\n]", len);
    return scanf(format, buffer) ;
}

#define MAX_CHARS 20

int main(void) {
    char buffer[MAX_CHARS + 1] ; // 20 characters + 1 for '[=11=]'
    read_chars (buffer, MAX_CHARS) ;
    printf("%s\n", buffer);
    return 0;
}

编辑: 如果您不想使用 sprintf 创建格式字符串,您可以使用预处理器(如果 MAX_CHARS 将不起作用不是预处理器常量):

#include <stdio.h>

#define _READ_CHARS(buffer, N) scanf("%" #N "[^\n]", buffer)
#define READ_CHARS(buffer, N) _READ_CHARS(buffer, N)

#define MAX_CHARS 20

int main(void) {
    char buffer[MAX_CHARS + 1] ; // 20 characters + 1 for '[=12=]'
    READ_CHARS (buffer, MAX_CHARS) ;
    printf("%s\n", buffer);
    return 0;
}

只需使用阅读:

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

    int main(){
        //Declare the reading buffer. Need 1 more position to add '[=10=]'
        char buffer[21];

        int char_num;
        if ((char_num = read(0, buffer, 20)) < 0) {
            perror("read: ");
            exit(1);
        }
        //means that there were less than 20 chars in stdin
        //add the null character after the last char and return
        else if (char_num < 20) {
            //terminate the string after the last char read from stdin
            buffer[char_num] = '[=10=]';
            close(0);
            printf("%s\n", buffer);
        }
        //means that there were more than 20 (or exactly 20 chars on stdin)
        else {
            buffer[20] = '[=10=]';
            printf("%s\n", buffer);
            //now it depends on what you want to do with the remaining chars
            //this read just discard the rest of the data, in the same buffer
            //that we ve used. If you want to keep this buffer for some other
            //task, figure out some other solution
            while(1) {
                if ((char_num = read(0, buffer, 20)) < 0) {
                    perror("read: ");
                    exit(1);
                }
                close(0);
                if (char_num == 0 || char_num < 20)
                    break;
            }
        }
        return 0;
    }