该程序的目标是获取输入文本文件,取出每个单词并对第一个和最后一个字母之间的字母进行加扰,然后将加扰文本写入输出文件。这是我提出的代码:
void processFile(FILE* ifp, FILE* ofp) {
printf("Begin file processing\n");
char istr[MAXLINE], iword[50];
char* token;
char delimit[] = {" \t\r\n\v\f"};
while(fgets(istr,MAXLINE,ifp)!= NULL) {
token = strtok(istr,delimit);
scramble(token);
fputs(token,ofp);
fputs(" ", ofp);
while(token != NULL) {
token = strtok(NULL,delimit);
scramble(token);
fputs(token,ofp);
fputs(" ",ofp);
}
}
printf("End file processing\n");
} /* processFile */
void scramble(char str[50]) {
printf("\nWord Scramble Start\n");
int len = strlen(str);
printf("strlen: %d\n",len);
int i = 0;
if(len > 3) {
int t = str[1];
for (int k = 1; k < len - 2; k++) str[k] = str[k + 1];
str[len - 2] = t;
printf("str: %s\n",str);
}
}
根据我的调试尝试,一旦程序到达换行符,似乎就会发生崩溃,即使它在此之前似乎正常工作。这看起来很奇怪,因为我确实在strtok()的分隔符中包含了换行符。非常感谢任何帮助!
答案 0 :(得分:1)
每次调用时,检查是否从strtok()
获得了非空令牌。
#include <stdio.h>
#include <string.h>
enum { MAXLINE = 4096 };
extern void processFile(FILE *ifp, FILE *ofp);
extern void scramble(char str[]);
void processFile(FILE *ifp, FILE *ofp)
{
printf("Begin file processing\n");
char istr[MAXLINE];
char *token;
char delimit[] = {" \t\r\n\v\f"};
while (fgets(istr, MAXLINE, ifp) != NULL)
{
if ((token = strtok(istr, delimit)) != NULL)
{
scramble(token);
fputs(token, ofp);
fputs(" ", ofp);
while ((token = strtok(NULL, delimit)) != NULL)
{
scramble(token);
fputs(token, ofp);
fputs(" ", ofp);
}
}
}
printf("End file processing\n");
}
void scramble(char str[])
{
printf("\nWord Scramble Start\n");
int len = strlen(str);
printf("strlen: %d\n", len);
if (len > 3)
{
int t = str[1];
for (int k = 1; k < len - 2; k++)
str[k] = str[k + 1];
str[len - 2] = t;
printf("str: %s\n", str);
}
}
int main(void)
{
processFile(stdin, stdout);
return 0;
}
保存为scramble97.c
。以./scramble97 < scramble97.c
运行时,输出为:
Begin file processing
Word Scramble Start
strlen: 8
str: #ncludie
#ncludie
Word Scramble Start
strlen: 9
str: <tdio.hs>
<tdio.hs>
Word Scramble Start
strlen: 8
str: #ncludie
#ncludie
Word Scramble Start
strlen: 10
str: <tring.hs>
<tring.hs>
Word Scramble Start
strlen: 4
str: eunm
eunm
Word Scramble Start
strlen: 1
{
Word Scramble Start
strlen: 7
str: MXLINAE
MXLINAE
Word Scramble Start
strlen: 1
=
Word Scramble Start
strlen: 4
str: 4906
4906
Word Scramble Start
strlen: 2
};
Word Scramble Start
strlen: 6
str: eterxn
eterxn
Word Scramble Start
strlen: 4
str: viod
viod
Word Scramble Start
…
Word Scramble Start
strlen: 12
str: pintf("strr:
pintf("strr:
Word Scramble Start
strlen: 6
str: %\n"s,
%\n"s,
Word Scramble Start
strlen: 5
str: sr)t;
sr)t;
Word Scramble Start
strlen: 1
}
Word Scramble Start
strlen: 1
}
Word Scramble Start
strlen: 3
int
Word Scramble Start
strlen: 10
str: min(voida)
min(voida)
Word Scramble Start
strlen: 1
{
Word Scramble Start
strlen: 18
str: pocessFile(stdinr,
pocessFile(stdinr,
Word Scramble Start
strlen: 8
str: sdout)t;
sdout)t;
Word Scramble Start
strlen: 6
str: rturen
rturen
Word Scramble Start
strlen: 2
0;
Word Scramble Start
strlen: 1
} End file processing
在摆脱大部分进度报告打印后,您可能需要处理添加换行符。请注意,我删除了几个死(未使用)变量,并从&#39;数组大小&#39;中移除了50
。到scramble()
函数。我也将MAXLINE
设置得足够大。从标准输入读取和写入标准输出是我能想到的最简单的代码测试工具。
您可以通过其他修改来减少processFile()
中的重复次数:
#include <stdio.h>
#include <string.h>
enum { MAXLINE = 4096 };
extern void processFile(FILE *ifp, FILE *ofp);
extern void scramble(char str[]);
void processFile(FILE *ifp, FILE *ofp)
{
printf("Begin file processing\n");
char istr[MAXLINE];
char *token;
char delimit[] = {" \t\r\n\v\f"};
while (fgets(istr, MAXLINE, ifp) != NULL)
{
char *start = istr;
while ((token = strtok(start, delimit)) != NULL)
{
scramble(token);
fprintf(ofp, "%s ", token);
start = NULL;
}
putchar('\n');
}
printf("End file processing\n");
}
void scramble(char str[])
{
//printf("\nWord Scramble Start\n");
int len = strlen(str);
//printf("strlen: %d\n", len);
if (len > 3)
{
int t = str[1];
for (int k = 1; k < len - 2; k++)
str[k] = str[k + 1];
str[len - 2] = t;
//printf("str: %s\n", str);
}
}
int main(void)
{
processFile(stdin, stdout);
return 0;
}
不是重复对scramble()
和fputs()
的调用,而是将它全部包装在一个循环中,使用fprintf()
进行单个I / O操作。它确实留下了空白的空白;也有办法解决这个问题。