在 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;
}
我想读入 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
(容易出错):
#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;
}