【发布时间】:2011-02-25 10:58:15
【问题描述】:
我想从标准输入中获取一个字符串,但我不想要一个固定大小的静态数组
我知道 scanf 需要一些东西来保存标准输入,但我不能这样做:
char string[10]
scanf("%s",string);
因为我需要知道字符串要多长时间才能分配正确的内存空间。
你能帮我解决这个问题吗?
呜呜呜
我仍然被这个问题锁定...... 我要疯了
你能给我工作代码吗?
【问题讨论】:
我想从标准输入中获取一个字符串,但我不想要一个固定大小的静态数组
我知道 scanf 需要一些东西来保存标准输入,但我不能这样做:
char string[10]
scanf("%s",string);
因为我需要知道字符串要多长时间才能分配正确的内存空间。
你能帮我解决这个问题吗?
呜呜呜
我仍然被这个问题锁定...... 我要疯了
你能给我工作代码吗?
【问题讨论】:
唯一确定的方法是循环;一次读取一个字符并存储。如果您分配的缓冲区已满,请将其增大一些合适的量(建议一次超过一个字节以提高性能,经典的经验法则是将其加倍)。
当您认为字符串结束时停止,可能在换行符或 EOF 处。
【讨论】:
您可以使用以下方法逐字符处理输入数据:
int getc(FILE *stream);
或
int getchar(void);
【讨论】:
您可以使用以下格式字符串:
char string[10];
scanf("%10s" string);
这会强制遵守缓冲区边界,但要求格式字符串了解缓冲区的大小。我通常通过将两者都声明为常量来克服这个问题:
#define BUFSIZE 10
#define BUFFMT "%10s"
如果您在 GNU 系统上工作,您还可以利用 GNU 扩展:getline(3) 函数可以避免很多麻烦!看看here。
【讨论】:
您可以确保不会像这样过度运行缓冲区:
char buffer[128];
printf("Input Text: ");
fgets(buffer,127,stdin);
然后,如果您需要可变大小的输入,您只需保持相同的固定大小的输入量
【讨论】:
如果您不想要固定大小的静态数组,请考虑使用动态分配的数组,该数组会根据需要增长。
如果您在 Linux 或其他支持 POSIX 2008 的系统上工作,那么您可以使用(较新的)getline() 函数。如果您无法访问此类功能,请考虑使用相同的界面滚动您自己的功能。
【讨论】:
不要使用scanf,使用fgets,这样可以防止读入太多字符。
char tmp[256]={0x0};
while(fgets(tmp, sizeof(tmp), stdin)!=NULL)
{
printf("%s", tmp);
}
fgets 将在行尾返回一个 '\n',当 stdin 关闭或遇到错误时返回 NULL。
先玩它看看它的作用。如果您需要将输入行分解为字段,您可以在 tmp 上使用 sscanf(),sscanf 的工作方式与 scanf 类似,但在字符串上。
【讨论】:
如果您使用fgets(),那么如果缓冲区足够大,您很可能在缓冲区末尾有一个'\n' 字符。有些人可能希望通过strtok() 函数将其删除,但它是不安全的。
我建议使用以下安全方法来删除该额外的特殊字符。
char *get_line (char *s, size_t n, FILE *f)
{
char *p = fgets (s, n, f);
if (p != NULL) strtok (s, "\n");
return p;
}
【讨论】: