【发布时间】:2021-10-13 14:49:57
【问题描述】:
我实现了一个 read_line 函数:
#include<stdlib.h>
#include<stdio.h>
#include<stdbool.h>
char* read_line(){
const char UNIX_LINEBREAK = '\n';
const char WINDOWS_LINEBREAK = '\r';
const char C_STRING_TERMINATOR = '\0';
char extra_linebreak;
char current_letter;
char* line = NULL;
int position = 0;
bool reading_line = true;
while(reading_line){
scanf("%c", ¤t_letter);
if(current_letter == UNIX_LINEBREAK || current_letter == EOF){
reading_line = false;
}
else if(current_letter == WINDOWS_LINEBREAK) {
reading_line = false;
extra_linebreak = (char)getchar();
}
else {
line = (char*) realloc(line, sizeof(char) * (position + 1));
line[position] = current_letter;
position ++;
}
}
line = (char*) realloc(line, sizeof(char) * (position + 1));
line[position] = C_STRING_TERMINATOR;
return line;
}
我用它来读取格式的字符串:
operation number number
例如:
sum 13 13
但是,我正在使用可能(并且将会)溢出最大 int 大小的数字来执行操作。例如:
sum 23879238932898239832983298329839229383928329 239823983298392893289238932883290312803291832109230189
这迫使我以字符串格式读取它们,解析它们并最终通过链表使用它们(可能有更好的方法,但这还不是重点)。到目前为止,我正在尝试使用辅助缓冲区(operation、first_number_buffer 和second_number_buffer)和sscanf 将read_line 读取的行拆分为三个子字符串。
#include <stdio.h>
#include <readline.h>
#include <stdio.h>
#include <readline.h>
int main (){
char* line = read_line();
char operation[4];
char* first_number_buffer;
char* second_number_buffer;
sscanf(line, "%s %s %s", operation, first_number_buffer, second_number_buffer);
printf("%s\n%s\n%s\n", line,first_number_buffer,second_number_buffer);
}
上面的代码不能很好地工作,因为我还没有真正分配first_number_buffer 和second_number_buffer。我想知道在这种情况下是否有使用 sscanf 的有效方法。我没能在 google 中找到好的结果,因为 scanf 与 sscanf 结果重叠。
问题似乎是:通常,要动态分配字符串,使用realloc 将其大小一一增大。但是 sscanf 尝试一次“抛出”已解析子字符串的所有内容。由于字符串的大小不一致,我不能像使用 operation 那样简单地将它们设为静态。
是的,我可以使用一个大的静态缓冲区,但这似乎是一项重要的任务,而且由于我是一名本科生,我想知道正确的方法。提前致谢!
【问题讨论】:
-
scanf("%c", &current_letter);->current_letter = getchar();将current_letter的类型更改为int。 -
您对使用链表处理“大数字”的想法很好。这个网站上有一些例子。您可能希望以 1024 块为单位重新分配并跟踪空间
avaialble和used,并且仅在available == used时重新分配。realloc()每个字符都非常低效。 -
谢谢大卫!这是我前段时间制作的通用 read_line() 函数。问题不在于该功能,肯定有改进的方法(例如,我还没有将它划分为更小的功能),但它确实有效!我已经测试了我必须阅读的所有输入,问题肯定是分配缓冲区
-
你还没有为
first_number_buffer或second_number_buffer分配空间,所以当你执行sscanf(line, "%s %s %s", operation, first_number_buffer, second_number_buffer);时一切都乱套了。如果你有一个足够兼容 POSIX 的操作系统(运行时 C 库),你可以使用%ms作为这两个数字并传递&first_number_buffer和&second_number_buffer。否则,您必须对数字的长度施加限制(也许是 1024?)并从那里开始工作。 -
是的,我知道这不是你的问题,这就是为什么我用评论而不是答案来注明。
标签: c