[英]Read a line from console in C
已经够疯狂了,但是从 C 中的控制台读取一行简单的字符似乎非常非常困难... gets
、 fgets
、 getline
、 scanf
....事情,阅读一个简单的行,没有换行符......
那是什么语言? 我遵循这些答案,但我不明白如何存在一种仅从控制台读取字符串如此复杂的语言?
请有人指导我如何使用char* str
来读取控制台文本...
以下将从stdin
读取一行,然后删除换行符:
char buffer[260];
...
fgets(buffer, sizeof(buffer), stdin);
buffer[strcspn(buffer, "\n")] = 0;
C 库函数 char *fgets(char *str, int n, FILE *stream) 从指定的流中读取一行并将其存储到 str 指向的字符串中。 它在读取 (n-1) 个字符、读取换行符或到达文件结尾时停止,以先到者为准。
为了收集更大量的输入,可以在循环内调用此构造。 请注意,如何累积每个连续的缓冲区是另一个主题。
更多关于fgets()
@ryker 提供了一个很好的答案,可以解释大部分内容。 这是一个非常安全的实现,它是 100% 可移植的,并且允许您不必担心换行符、缓冲区溢出或分配。 但它返回一个您需要释放的指针。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *gline() {
char *buffer;
const size_t step = 10;
size_t size = step;
if(!(buffer = malloc(size))) goto CLEANUP;
char *s = buffer;
// step-1 is not strictly necessary, but some implementations of fgets
// are buggy. That's why it's step-1 instead of just step
while(fgets(s, step-1, stdin)) {
if(strchr(s, '\n')) break;
size += step;
if(!(buffer = realloc(buffer, size))) goto CLEANUP;
s = &buffer[strlen(buffer)];
}
buffer[strcspn(buffer, "\n")] = 0;
return buffer;
CLEANUP:
free(buffer);
return NULL;
}
int main(void) {
char *s = gline();
if(!s)
puts("Error reading line");
else
puts(s);
free(s);
}
我还没有对它进行微调,因此它可能分配了比需要更多的内存。 它也不是很有效,因为它在每次迭代中都运行strlen
。 但是只要分配没有失败,它就是安全且易于使用的。
像scanf
这样的内置函数可以做到这一点,但我对它们的问题是你需要提前知道你会收到多少输入。 如果是 1 个字符呢? 如果是10000呢? 所以我更喜欢使用malloc
和realloc
动态分配内存并在接收到输入时构建字符串。 当我需要从stdin
或文件中读取时,这就是我使用的。 它很简单,可能远非完美,它只是从流中获取一个字符,如果它不是换行符或EOF
则将其添加到字符串中。 如果重新分配失败,它会释放整个字符串,因为我需要采用“全有或全无”的方法来构建字符串。 它返回一个指向字符串或NULL
或任何失败的指针。
char* get_str(FILE* stream)
{
char *s;
int ix = 0, sz = 1, rf = 0, ch;
if(stream == NULL) {
s = NULL;
} else {
s = (char*)malloc(sizeof(char) * sz);
if(s != NULL) {
s[ix] = '\0';
ch = fgetc(stream);
while(ch != '\n' && ch != EOF && rf == 0) {
sz++;
s = (char*)realloc(s, sizeof(char) * sz);
if(s != NULL) {
s[ix] = ch;
ix++;
s[ix] = '\0';
ch = fgetc(stream);
} else {
rf = 1;
free(s);
s = NULL;
}
}
}
}
return s;
}
然后你这样称呼它:
int main()
{
char *s = get_str(stdin); /* or a file you opened with fopen, etc */
printf("%s\n", s);
free(s);
return 0;
}
请记住,需要释放使用malloc
、 calloc
或realloc
分配的malloc
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.