有两个文本,文本a是内容,文本b是逐行列出的。该程序是从内容中获取文本b中单词的位置。
这是我的计划:
#include<stdio.h>
#include<string.h>
#define WORDMAXLENGTH 30
#define MAXLENGTH 200
int main(){
typedef struct{
char stack[MAXLENGTH][WORDMAXLENGTH];
int top;
}stack;
stack query;
query.top = 0;
int i = 0, j = 0,q = 0;
char myArr[MAXLENGTH];
char *PosStr = NULL;
FILE *inFile = fopen("query.txt","r");
FILE *inFile2 = fopen("hello.txt","r");
while(fgets(query.stack[query.top],WORDMAXLENGTH,inFile) != NULL){
query.top++;
}
fgets(myArr,MAXLENGTH,inFile2);
for(i = 0; i < query.top; i++){
PosStr = strstr(myArr,query.stack[i]);//get the position of s2 (Q1)
printf("%d\n", PosStr - myArr + 1);
}
fclose(inFile);
fclose(inFile2);
return 0;
}
Q1。这个等式对吗?如果错了,我怎么能得到这个职位?如果是对的,为什么我不能正确得到这个位置?另外,PosStr的一些结果是0。
答案 0 :(得分:2)
我认为该程序旨在检查第一个文件中的每个单词列表,以便在第二个文件的单个文本行中出现,并且通过一些调整,它可以正常工作。
我添加了一些错误检查,并从文件输入中删除了尾随的newline
。在根据strstr()
打印值之前,我检查了NULL
的结果。我还添加了另一个#define
来区分堆栈的大小和测试字符串的长度,并检查堆栈是否溢出。
UPDATE 修改代码以检查整个单词 - 不区分大小写。
#include<stdio.h>
#include<string.h>
#define WORDMAXLENGTH 30
#define MAXENTRY 200
#define MAXLENGTH 200
typedef struct{
char stack[MAXENTRY][WORDMAXLENGTH];
int top;
} stack;
int main(){
FILE *inFile;
FILE *inFile2;
int i, w;
char myArr[MAXLENGTH];
char *sptr;
stack query;
query.top = 0;
inFile = fopen("query.txt","r");
inFile2 = fopen("hello.txt","r");
if (inFile == NULL || inFile2 == NULL) {
printf("Cannot open both files\n");
return 1;
}
while(fgets(query.stack[query.top], WORDMAXLENGTH, inFile) != NULL){
i = strcspn(query.stack[query.top], "\r\n");
query.stack[query.top][i] = 0; // remove trailing newline etc
if (++query.top >= MAXENTRY) // check stack full
break;
}
fgets(myArr,MAXLENGTH,inFile2);
//myArr [ strcspn(myArr, "\r\n") ] = 0; // remove trailing newline etc
w = 1; // word count
sptr = strtok(myArr, " \t\r\n"); // removes trailing stuff anyway
while (sptr) { // each word in test string
for(i=0; i<query.top; i++) { // each word in library list
if (stricmp(sptr, query.stack[i]) == 0) // without case
printf("%-4d %s\n", w, query.stack[i]);
}
w++;
sptr = strtok(NULL, " \t\r\n");
}
fclose(inFile);
fclose(inFile2);
return 0;
}
档案query.txt
:
cat
dog
fox
rabbit
档案hello.txt
:
A quick brown fox jumps over the lazy dog
节目输出:
4 fox
9 dog
答案 1 :(得分:0)
唯一的问题是fgets()
将'\n'
放入缓冲区,从而使strstr()
尝试匹配该字符,有多种技术可以删除该字符,简单的一种是
strtok(myArr, "\n");
在fgets()
工作之后,因为strtok()
会将'\n'
替换为'\0'
。或
size_t length = strlen(myArr);
myArr[length - 1] = '\0';
答案 2 :(得分:0)
我不完全确定我理解这个问题,但我猜测“query.txt”(它被读入堆栈对象)由单词行组成(每行不超过30个字符),喜欢 一些单词 更多的话 在一条线上的文字 而“hello.txt”包含一行,您要搜索的单词: 字 你希望程序产生输出: 6 11 1 1 对于上述输入。
正如评论中所提到的,fgets()函数将在它读取的缓冲区中包含终止'\ n'。 此外,strstr()函数接受参数 char * strstr(const char * haystack,const char * needle); 也就是说,第一个参数是你要搜索一个小字符串(针)的大字符串(haystack)。它返回一个指向大海捞针的指针,找到针的位置。因此,如果我理解你的问题,程序应该成为:
#include<stdio.h>
#include<string.h>
#define WORDMAXLENGTH 30
#define MAXLENGTH 200
int
main()
{
typedef struct {
char stack[MAXLENGTH][WORDMAXLENGTH];
int top;
} stack;
stack query;
query.top = 0;
int i = 0, j = 0, q = 0;
char myArr[MAXLENGTH];
char *PosStr = NULL;
FILE *inFile = fopen("query.txt", "r");
FILE *inFile2 = fopen("hello.txt", "r");
while (fgets(query.stack[query.top], WORDMAXLENGTH, inFile) != NULL) {
query.top++;
}
fgets(myArr, MAXLENGTH, inFile2);
myArr[strlen(myArr)-1] = 0;
for (i = 0; i < query.top; i++) {
PosStr = strstr(query.stack[i], myArr); //get the position of s2 (Q1)
printf("%d\n", PosStr -query.stack[i] + 1);
}
fclose(inFile);
fclose(inFile2);
return 0;
}
特别是,你正在寻找针头中的干草堆,针头实际上并不是你想要的!
答案 3 :(得分:0)
Note: comments beginning with '// --' are reasons for following code changes
#include<stdio.h>
#include<stdlib.h> // exit(), EXIT_FAILURE
#include<string.h>
// --wrap #define number in parens
// --vertical alignment make the code easier to read
// --vertical spacing makes the code easier to read
#define WORDMAXLENGTH (30)
#define MAXLENGTH (200)
// --place data type definitions outside of any function
// --in modern C, for struct definitions just declare the struct
// --and don't clutter the code with typedef's for struct definitions
struct stack
{
char stack[MAXLENGTH][WORDMAXLENGTH];
int top;
};
// --place large data struct in file global memory, not on stack
// contains search keys and number of search keys
static struct stack query;
// --using Georgian formatting for braces makes the code harder to read
// --indent code blocks within braces for readabillity
int main()
{
query.top = 0;
// --while legal C, multiple variable declarations on same line
// --leads to maintenance problems and reduces readability
int i = 0;
// -- eliminate unused variables
//int j = 0;
//int q = 0;
char myArr[MAXLENGTH]; // line to search
char *PosStr = NULL; // ptr to where search key found
// --always check the returned value from fopen to assure operation successful
// --always place the literal on the left in comparisons
// -- so compiler can catch errors like using '=' rather than '=='
FILE *inFile = fopen("query.txt","r");
if( NULL == inFile )
{ // then fopen failed
perror( "fopen for query.txt for read failed" );
exit( EXIT_FAILURE );
}
// implied else, fopen successful
FILE *inFile2 = fopen("hello.txt","r");
if( NULL == inFile2 )
{ // then, fopen failed
perror( "fopen for hello.txt for read failed" );
fclose(inFile); // cleanup
exit( EXIT_FAILURE );
}
// implied else, fopen successful
// --the following while loop can
// -overflow the available space in the struct
// --leading to undefined behaviour and can/will lead to a seg fault event
// --comment the code so reverse engineering is not needed
// note: each search key in the struct field: stack[] will be terminated with '\n'
// so eliminate them
// read in complete file. line-by-line to struct
// while tracking number of lines
while(fgets(query.stack[query.top],WORDMAXLENGTH,inFile))
{
query.top++;
strtok(myArr, "\n"); // replace newline with NUL char
} // end while
// --always check returned value from fgets
// --to assure the operation was successful
// read line to search
if( NULL == fgets(myArr,MAXLENGTH,inFile2) )
{ // then fgets failed
perror( "fgets for hello.txt file failed" );
exit( EXIT_FAILURE );
}
// implied else, fgets successful
for(i = 0; i < query.top; i++)
{
// --strstr will return NULL if search string not found
// --always check returned value from strstr (!=NULL) to assure successful operation
PosStr = strstr(myArr,query.stack[i]);//get the position of s2 (Q1)
if( PosStr )
{ // then at least one instance of current search key found in line
// --difference between two pointer is a 'long int', not an 'int'
// display offset into line
printf("%ld\n", PosStr - myArr + 1);
} // end if
} // end for
fclose(inFile);
fclose(inFile2);
return 0;
} // end function: main