是否可以使用scanf()读取文本行 - 排除\n
并打破特殊(选定)字符,但包含该字符
这是我目前的表达:while(scanf("%49[^:\n]%*c", x)==1)
但是这个被排除在:
之外。
是否有可能打破:
上的阅读但是也读过这个角色?
答案 0 :(得分:4)
好的我正在使用 Johannes-Schaub-litb的代码。
char * getline(char cp) {
char * line = malloc(100), * linep = line;
size_t lenmax = 100, len = lenmax;
int c;
if(line == NULL)
return NULL;
for(;;) {
c = fgetc(stdin);
if(c == EOF)
break;
if(--len == 0) {
len = lenmax;
intptr_t diff = line - linep;
char * linen = realloc(linep, lenmax *= 2);
if(linen == NULL) {
free(linep);
return NULL;
}
line = linen + diff;
linep = linen;
}
if((*line++ = c) == cp)
break;
}
*line = '\0';
return linep;
}
我仍然使用此代码......它运行正常。 稍后会对代码进行修改。
答案 1 :(得分:0)
我以一种不同的方式做到了这一点。也许这会在Windows上崩溃。但是,无论如何它在这里。希望能帮助到你。圣诞节快乐。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
char *input_str;
/**
* Dynamic memory allocation.
* Might crash on windows.
*/
int status = scanf("%m[^.]", &input_str);
/**
* If the first character is the
* terminating character then scanf scans nothing
* and returns 0.
*/
if (status > 0) {
/**
* Calculate the length of the string.
*/
size_t len = strlen(input_str);
/**
* While allocating memory provide
* two extra cell. One for the character
* you want to include.
* One for the NULL character.
*/
char *new_str = (char*) calloc (len + 2, sizeof(char));
/**
* Check for memory allocation.
*/
if(new_str == NULL) {
printf("Memory Allocation failed\n");
exit(1);
}
/**
* Copy the string.
*/
strcpy(new_str, input_str, len);
/**
* get your desired terminating character
* from buffer
*/
new_str[len++] = getc(stdin);
/**
* Append the NULL character
*/
new_str[len++] = '\0';
/**
* eat other characters
* from buffer.
*/
while(getc(stdin) != '\n');
/**
* Free the memory used in
* dynamic memory allocation
* in scanf. Which is a must
* according to the scanf man page.
*/
free(input_str);
} else {
char new_str[2] = ".\0";
/**
* eat other characters
* from buffer.
*/
while(getc(stdin) != '\n');
}
}
编辑: - 我使用点作为终止字符。
答案 2 :(得分:0)
是否可以使用scanf()读取文本行 - 排除\ n并打破特殊(选定)字符,但包含该字符(?)
是。但scanf()
因使用错误而难以正确使用而臭名昭着。当然,scanf()
方法适用于大多数用户输入。只有罕见的实施才能完全达到OP的目标,而不会遗漏角落案例。 IMO,这不值得。
或者,让我们尝试直接方法,重复使用fgetc()
。一些未经测试的代码:
char *luvatar_readline(char *destination, size_t size, char special) {
assert(size > 0);
char *p = destitution;
int ch;
while (((ch = fgetc(stdin)) != EOF) && (ch != '\n')) {
if (size > 1) {
size--;
*p++ = ch;
} else {
// Ignore extra input or
// TBD what should be done if no room left
}
if (ch == (unsigned char) special) {
break;
}
}
*p = '\0';
if (ch == EOF) {
// If rare input error
if (ferror(stdin)) {
return NULL;
}
// If nothing read and end-of-file
if ((p == destination) && feof(stdin)) {
return NULL;
}
}
return destination;
}
样本用法
char buffer[50];
while (luvatar_readline(buffer, sizeof buffer_t, ':')) {
puts(buffer);
}
角落案件待定:如果special
为'\n'
或'\0'
,则不清楚OP需要什么。
OP while(scanf("%49[^:\n]%*c", x)==1)
有很多问题。
无法处理开始与:
或'\n'
的输入,而x
未设置。
不知道非:
,非'\n'
输入后的字符是:
,'\n'
,EOF。
不会消耗超过49的额外输入。
使用固定的空格字符':'
,而非普通字符。
答案 3 :(得分:0)
我认为你想这样做:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
char *line = NULL;
size_t len = 0;
ssize_t read;
while ((read = getline(&line, &len, stdin)) != -1) {
if (read > 0 && line[read - 1] == '\n') {
if (read > 1 && line[read - 2] == '\r') {
line[read - 2] = '\0'; // we can remove the carriage return
}
else {
line[read - 1] = '\0'; // we can remove the new line
}
}
char const *delim = ":";
printf("parsing line :\n");
char *token = strtok(line, delim);
while (token != NULL) {
printf("token: %s\n", token);
token = strtok(NULL, delim);
}
}
free(line);
}