在C中遍历stdin中的字符串

在C中遍历stdin中的字符串,c,iteration,scanf,stdin,C,Iteration,Scanf,Stdin,我想读入stdin中的前20个字符。我能否只使用一个循环20次的for循环和scanf(“%c”,&var)?如果输入长度小于20个字符,会发生什么情况 我正在考虑使用get()来绕过这个问题。读入整行,然后在字符串上迭代,直到计数器达到20或字符串的末尾。但是,有没有一种方法可以检测字符串的结尾 还是有更好的办法 之所以问这个问题,是因为我们不允许使用string.h库中的任何函数。您可以尝试这种方法 1-在字符数组中使用scanf()读取一行的前20个字符,如下例所示 例如: char

我想读入
stdin
中的前20个字符。我能否只使用一个循环20次的for循环和
scanf(“%c”,&var)
?如果输入长度小于20个字符,会发生什么情况

我正在考虑使用
get()
来绕过这个问题。读入整行,然后在字符串上迭代,直到计数器达到20或字符串的末尾。但是,有没有一种方法可以检测字符串的结尾

还是有更好的办法


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

您可以尝试这种方法

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

例如:

  char str[21];

  scanf("%20[^\n]s",str);
2-最后,您将拥有字符数组中第行的前20个字符

3-如果行长度小于20,则会自动在行尾指定“\0”字符

如果要查找数组中的字符总数,请计算数组的长度


**字符串的结尾是通过使用'\0'空字符来确定的。

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

#包括
#定义LEN(arr)((int)(sizeof(arr)/sizeof(arr)[0]))
静态void ReadLine(FILE*FILE,char result[],int resultLen)
{
int i,ch;
ch=fgetc(文件);
i=0;
而((ch!=EOF)&&(ch!='\n')&&(i
以下是一个简短的版本,它使用:

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

#包括
#定义_READ_CHARS(buffer,N)scanf(“%”N“[^\N]”,buffer)
#定义读取字符(缓冲区,N)\读取字符(缓冲区,N)
#定义最大字符数20
内部主(空){
字符缓冲区[MAX_CHARS+1];//20个字符+1表示“\0”
读取字符(缓冲区,最大字符);
printf(“%s\n”,缓冲区);
返回0;
}
只需使用read:

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

    int main(){
        //Declare the reading buffer. Need 1 more position to add '\0'
        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] = '\0';
            close(0);
            printf("%s\n", buffer);
        }
        //means that there were more than 20 (or exactly 20 chars on stdin)
        else {
            buffer[20] = '\0';
            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;
    }
#包括
#包括
#包括
int main(){
//声明读取缓冲区。还需要1个位置才能添加“\0”
字符缓冲区[21];
int char_num;
如果((char_num=read(0,buffer,20))<0){
佩罗尔(“读:”);
出口(1);
}
//意味着stdin中只有不到20个字符
//在最后一个字符后添加空字符并返回
否则如果(字符数<20){
//在从stdin读取最后一个字符后终止字符串
缓冲区[char_num]='\0';
关闭(0);
printf(“%s\n”,缓冲区);
}
//意味着有超过20个字符(或者说stdin上正好有20个字符)
否则{
缓冲区[20]='\0';
printf(“%s\n”,缓冲区);
//现在,这取决于您要如何处理剩余的字符
//此读取操作将丢弃同一缓冲区中的其余数据
//我们已经用过了。如果你想把这个缓冲区留给其他人
//任务,找出其他解决方案
而(1){
如果((char_num=read(0,buffer,20))<0){
佩罗尔(“读:”);
出口(1);
}
关闭(0);
if(char_num==0 | char|u num<20)
打破
}
}
返回0;
}

您能告诉我们到目前为止您尝试了什么吗?请阅读缓冲输入,如果输入长度小于20个字符,它将妨碍您,
scanf()
当您经过结尾时将返回
0
。字符串的结尾由一个
\0
字符表示。@holt为什么这么说?因为
get
不安全,它将读取到
\n
字符的所有内容,不管您的缓冲区是否足够长,都可以存储它。在SO(我发布的链接就是其中之一)和其他网站上有很多帖子解释了为什么不应该使用
gets
。但如果这行包含空格字符,那么他必须使用gets()来阅读整行内容。否则,它最多只能读取空格字符no。如果您不想使用
scanf
,您可以使用
fgets
,这几乎等同于
gets
,但是安全的。但是也可以使用
scanf
读取带空格的行,例如使用
“%[^\n]20s”
格式。那又如何呢?“不允许使用string.h库中的任何函数。”@sestus好的,我现在不使用strlen.EOF是一个int,您不应该将它与char进行比较。在某些平台上,此代码将永远循环。@TomTanner感谢您的注意。我现在已经更新了代码。据我所知,无法使用scanf编写通用的行读取函数,因为宽度说明符不能成为变量,还是我错了?@AugustKarlstrom查看我的编辑,您可以动态创建格式字符串,您只需小心
格式
字符串长度(我认为在这种情况下50美元就足够了)。
#include <stdio.h>

int main(void) {
    char buffer[20 + 1] ; // 20 characters + 1 for '\0'
    int  nread ;
    nread = scanf("%20[^\n]", buffer) ; // Read at most 20 characters
    printf("%s\n", buffer);
    return 0;
}
#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 '\0'
    read_chars (buffer, MAX_CHARS) ;
    printf("%s\n", buffer);
    return 0;
}
#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 '\0'
    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 '\0'
        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] = '\0';
            close(0);
            printf("%s\n", buffer);
        }
        //means that there were more than 20 (or exactly 20 chars on stdin)
        else {
            buffer[20] = '\0';
            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;
    }