我有一个绝对最疯狂的时间来获得全线输入。我会解释我的问题。我需要从键盘输入的用户那里获得一整行输入,包括空格。简单吧?错!
将带有空格的多个字符串存储到变量中。如果它有所不同,我想让变量等于char
指针。因此,一旦我从tempString
获得输入,我想将其设置为char
指针。像这样:
char *variable1, *variable2;
//get user input
variable1 = tempString;
//get more user input
variable 2 = tempString;
//etc etc etc
这是我尝试过的。
char tempString[100];
scanf("%s", &tempString);
printf("%s", tempString);
无效:scanf
将停止在空格处阅读,因此“Example String
”最终会变为“Example
”。
所以我做了更多的研究。我以为我找到了神奇的修复。
char tempSTring[100];
fgets(tempString, 100, stdin);
printf("%s", tempString);
最初这是有效的。然而,存在一个大问题。我需要让用户输入大约8个输入。意思是我必须使用这样的命令8次。问题是程序经常跳过fgets
命令。如果我以前使用过scanf
,那么\n
字符会在输入流中卡住,并自动输入fgets
,满足其stdin input
,然后不会提示用户输入。
在考虑fgets
可能是我的解决方案之后,我尝试了一些技巧。
char tempSTring[100];
getc(stdin);
fgets(tempString, 100, stdin);
printf("%s", tempString);
我尝试添加此getc(stdin)
行。它适用于我的大部分计划。它吸收流中留下的\n
字符。当它这样做,很棒,它的工作原理。但有时,出于某种原因,\n
不会留在流中,并且在调试时,看起来getc(stdin)
正在请求来自用户的输入,因此它会暂停我的程序以请求输入。 / p>
这些对我不起作用。
答案 0 :(得分:6)
要从文件中读取(最多)8行,您可以使用这些解决方案中的任何一种。我拒绝使用变量char *variable1, *variable2, …;
- 这是一个寻求逃避的数组。
getline()
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
enum { MAX_LINES = 8 };
char *lines[MAX_LINES];
int index = 0;
char *buffer = 0;
size_t buflen = 0;
while (index < MAX_LINES && getline(&buffer, &buflen, stdin) != -1)
{
lines[index++] = buffer;
buffer = 0;
buflen = 0;
}
free(buffer); // Space may be allocated before EOF is detected
for (int i = 0; i < index; i++)
printf("%d: %s", i, lines[i]);
return 0;
}
如果getline()
无法分配内存,它将报告错误,因此无需进行显式错误检查。
fgets()
代码使用strdup()
,另一个POSIX函数。它不是标准C的一部分(虽然它可以广泛使用)。实施起来很简单。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
enum { MAX_LINES = 8 };
char *lines[MAX_LINES];
int index = 0;
char buffer[4096];
while (index < MAX_LINES && fgets(buffer, sizeof(buffer), stdin) != 0)
{
if ((lines[index] = strdup(buffer)) == 0)
break;
index++;
}
for (int i = 0; i < index; i++)
printf("%d: %s", i, lines[i]);
return 0;
}
循环中的测试允许strdup()
无法分配内存。
上述两种解决方案都将换行符保留在输入字符串的末尾。如果你不想那样,你可以用:
来消除它lines[i][strcspn(lines[i], "\r\n")] = '\0';
这会用空字节覆盖回车符或换行符,转换DOS或Unix行结尾。然后,您需要调整打印,假设字符串包含换行符。请注意,即使字符串中没有回车符或换行符,显示的表达式也能正常工作。
fgets()
解决方案将断开4095个字符的行,其余部分将被读作“下一行”。如果这是不可接受的,您可以采取各种策略。
您可以阅读换行符或EOF之前的剩余字符:
int c;
while ((c = getchar()) != EOF && c != '\n')
;
strdup()
如果由于某种原因您的系统没有strdup()
的实施,您可以创建一个代理:
#include <assert.h>
#include <stdlib.h>
#include <string.h>
char *strdup(const char *old_str)
{
assert(old_str != 0);
size_t old_len = strlen(old_str) + 1;
char *new_str = malloc(old_len);
if (new_str != 0)
memmove(new_str, old_str, old_len);
return new_str;
}
答案 1 :(得分:2)
以下是我们老屁C程序员如何做到这一点:
#include <stdio.h>
#define MAX_LEN 100
int main( )
{
int c;
char input[MAX_LEN+1];
int i = 0;
while ( (c=getchar()) != '\n' && c != EOF && i < MAX_LEN)
input[i++] = c;
if (c == EOF || c =='\n') {
/* received input that terminated within buffer limit */
input[i] = '\0';
printf("read in your input string of: %s\n", input);
}
else {
printf("don't buffer overflow me dude!\n");
return -1;
}
return 0;
}
但是现在人们会告诉你使用其中一个库函数。我虽然仍然是一个老屁。
编辑:修正了以下有用评论中指出的令人尴尬的错误。
答案 2 :(得分:1)
您可以像以前那样写下'\n'
之前留下的scanf
-
scanf("%d%*c", &x); //<-- example to take int input
%*c
将从stdin
开始阅读,然后将其丢弃,'\n'
将从stdin
中删除。
您可以使用此scanf
来实现(以前尝试的方式) -
char tempString[100];
/* As suggested by chqrile it is essential to check return of scanf */
if(scanf("%99[^\n]", tempString)!=1){
// ^^ & not required
tempString[0]='\0';
}
%99[^\n]
这将读取99
个字符,并且只有在遇到'\n'
后才会停止,因此会读取带空格的输入。