提问人:user20125552 提问时间:9/28/2023 最后编辑:Jonathan Leffleruser20125552 更新时间:9/28/2023 访问量:50
如何使用空格和换行符遍历文本文件,对每个字符串执行函数,然后以原始格式再次打印出来?
How to iterate through text file with whitespace and newlines, perform a function upon each string, and print out again in the original format?
问:
我需要浏览类似格式的文本文件,如下所示:
fire dwarf stone
rock beer arrow lion
sword shield
archstone
dragon gold
silver
hall
goblet chest axe
Axe 后面有一个换行符(“axe\n”)。我需要将每个单词传递到一个函数中,然后在相同的位置、空格和换行符完全相同的位置打印回每个修改后的单词。
我遇到了成为 C 新手的问题。我发现了一些复杂的字符串格式选项,允许我从这里取一整行,包括空格,但我无法从行中提取单个单词。如果我只浏览整个文件,我无法弄清楚如何检查换行符,也无法弄清楚如果我这样做将如何保存位置。fscan("%s", word)
我尝试遍历字符串,使用字符作为跟踪器,将每个字符复制到一个新字符串中,每当跟踪器字符遇到“”时,我都会返回该字符串,但后来我不知道如何查看是否有换行符,因为使用两个字符跟踪器来检查“\”和“n”不起作用。
我目前的尝试是
while (fscanf(filename, "%s", line) == 1) {
if (...) {
printf("%s ", line);
} else {
printf("%se ", line);
}
if (getchar() == '\n') printf("\n");
}
但这也行不通。我可能只是在搜索错误的问题,但我根本找不到任何方法来查看是否有换行符,同时根据需要单独解析单词。
答:
1赞
Fe2O3
9/28/2023
#1
考虑将其编写为过滤器,处理 和 .这极大地简化了代码!以下内容将满足您的需求,并迅速而沉着!stdin
stdout
#include <stdio.h>
#include <ctype.h>
char *procWrd( char *word ) {
static char obuf[ 64 ];
sprintf( obuf, "%s-%.2s", word, word );
return obuf;
}
int main( void ) {
int ch;
char word[ 64 ]; // big enough!
int wrdChr = 0;
while( ( ch = getchar() ) != EOF )
if( isspace( (unsigned char)ch ) ) { // guaranteed LF at EOF
if( wrdChr ) {
word[ wrdChr ] = '\0'; // terminate string
printf( "%s", procWrd( word ) ); // output modified version
wrdChr = 0; // reset
}
putchar( ch ); // output whitespace
} else
word[ wrdChr++ ] = ch; // buffer characters of word
return 0;
}
我调整每个单词的版本如下所示:
fire-fi dwarf-dw stone-st
rock-ro beer-be arrow-ar lion-li
sword-sw shield-sh
archstone-ar
dragon-dr gold-go
silver-si
hall-ha
goblet-go chest-ch axe-ax
运行文件两次以获得真正的乐趣:
猫文件.txt |项目 |prog > outfile.txt
0赞
Jonathan Leffler
9/28/2023
#2
使用 和 :fgets()
strspn()
strcspn()
#include <ctype.h>
#include <stdio.h>
#include <string.h>
static const char whisp[] = " \t\n";
static void mapper(size_t n_bytes, char *data)
{
for (size_t i = 0; i < n_bytes; i++)
{
unsigned char c = data[i];
if (isupper(c))
data[i] = tolower(c);
else if (islower(c))
data[i] = toupper(c);
/* else leave alone */
}
}
int main(void)
{
char line[2048];
while (fgets(line, sizeof(line), stdin))
{
char *data = line;
char *eol = line + strlen(line);
size_t n_bytes;
while (data < eol)
{
if ((n_bytes = strspn(data, whisp)) > 0)
{
fwrite(data, n_bytes, 1, stdout);
data += n_bytes;
}
if ((n_bytes = strcspn(data, whisp)) > 0)
{
mapper(n_bytes, data);
fwrite(data, n_bytes, 1, stdout);
data += n_bytes;
}
}
}
return 0;
}
使用“读取空格”循环的代码:
/* SO 7719-2181 */
#include <ctype.h>
#include <stdio.h>
#include <string.h>
static void mapper(size_t n_bytes, char *data)
{
for (size_t i = 0; i < n_bytes; i++)
{
unsigned char c = data[i];
if (isupper(c))
data[i] = tolower(c);
else if (islower(c))
data[i] = toupper(c);
/* else leave alone */
}
}
int main(void)
{
char line[1024];
while (scanf("%1023s", line) == 1)
{
mapper(strlen(line), line);
fputs(line, stdout);
int c;
while ((c = getchar()) != EOF && isspace(c))
putchar(c);
if (c != EOF)
ungetc(c, stdin);
}
return 0;
}
两者都对标准输入进行大小写转换,将其写入标准输出。例如,在其源代码上运行第二个程序会产生:
/* so 7719-2181 */
#INCLUDE <CTYPE.H>
#INCLUDE <STDIO.H>
#INCLUDE <STRING.H>
STATIC VOID MAPPER(SIZE_T N_BYTES, CHAR *DATA)
{
FOR (SIZE_T I = 0; I < N_BYTES; I++)
{
UNSIGNED CHAR C = DATA[I];
IF (ISUPPER(C))
DATA[I] = TOLOWER(C);
ELSE IF (ISLOWER(C))
DATA[I] = TOUPPER(C);
/* ELSE LEAVE ALONE */
}
}
INT MAIN(VOID)
{
CHAR LINE[1024];
WHILE (SCANF("%1023S", LINE) == 1)
{
MAPPER(STRLEN(LINE), LINE);
FPUTS(LINE, STDOUT);
INT C;
WHILE ((C = GETCHAR()) != eof && ISSPACE(C))
PUTCHAR(C);
IF (C != eof)
UNGETC(C, STDIN);
}
RETURN 0;
}
(两次出现 被转换为 ,并转换为 。代码的其余部分为大写,但标点符号保持不变。EOF
eof
SO
so
代码不会对输出操作进行错误检查——严格来说,它应该这样做。
评论
fscanf()
fgets()
getline()
strspn()
strcspn()
%s%c
axe
fscanf(filename, ...
让我怀疑你是否真的有一个打开的文件。对于指针来说,这不是一个好名字。FILE
while (fscanf(filename, "%s", line) == 1) {
filename
FILE *
FILE *fp;
ifp
fpin
fin
%s
if (getchar() == '\n') printf("\n");
int c; while ((c = getc(fp)) != EOF && isspace(c)) putchar(c); if (c != EOF) ungetc(c, fp);
filename
fp
fscanf()
%s
int c...
fgets()