使用strstr查找四个不同的部分单词

时间:2017-01-24 05:19:04

标签: c string

我希望找到包含 TP2 DP3 OP1 OP2 的字符串的一部分,在文本文件中。

在每一行上是一组不同的字符,最后使用这三个字符,但它们永远不会在同一行上。

一旦找到 OP2 ,我就可以打印它,但它不会打印出之前的三个。如果我注释掉 OP2 ,它会找到 OP1 ,如果我执行 OP1 OP2 ,则会找到 DP3 等等。

我不明白为什么一旦找到它就无法打印出所有四种不同的。

我使用了两种不同的方法,一种是我%进入strcpy,另一种是我按原样打印出来并且都不起作用。后来我希望它打印到具有四种搜索类型的行上的temp符号的右侧,但是在我解决了打印问题后,我将继续处理。任何帮助或原因将不胜感激。

=

2 个答案:

答案 0 :(得分:0)

char parts[MAX_LINE_LENGTH+1];
int len = strlen(parts);

parts在此代码中未初始化,因此无法保证包含字符串。即使它是,len将初始化该垃圾字符串的长度,这是无意义的,因此是无用的。

char DP3[3] = "DP3";

如果您对字符串的理解有效,您应该意识到这些字符串中有四个字符。以下程序演示了这一点:

#include <stdio.h>
int main(void) {
    printf("sizeof \"DP3\": %zu\n", sizeof "DP3");
}

你正在读一本书来学习C,对吧?您的书会向我们解释许多其他内容,因此我们不需要,strstr要求其操作数为 strings ,而字符串始终包含终止'\0' 。您的终止位置'\0'在哪里? strstr如何知道DP3指向的字符串的长度?

由于令牌的长度最多为三个字节,因此您目前只需要一次读取和存储最多三个字节来进行搜索(其中四个包括上面解释的终端字节;下面未经测试和未完成的示例);这个要求可能会改变,如果您决定引入更长(或动态大小)的令牌,您的光标将需要与最长令牌一样宽。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef unsigned char item[4];
int item_cmp(void const *x, void const *y) {
    return memcmp(x, y, sizeof (item));
}
int main(void) {
    item cursor = "",
         haystack[] = { "TP1", "OP0", "OP1", "OP2", "TP0", "DP3", "OOO" };

    size_t size  = fread(cursor, sizeof cursor - 1, 1, stdin),
           nelem = sizeof haystack / sizeof *haystack;

    int c = 0, e = !size;

    qsort(haystack, nelem, sizeof *haystack, item_cmp);

    do {
        if (bsearch(cursor, haystack, nelem, sizeof *haystack, item_cmp)) {
            printf("match found for %s\n", cursor);
        }
        memmove(cursor, cursor + 1, sizeof cursor - 1);
        if (!e) {
            c = fgetc(stdin);
            e = c < 0 && feof(stdin);
        }
        cursor[size] = e || c == '\n' ? '\0' : c;
        size -= e;
    } while (size);

    exit(0);
}

答案 1 :(得分:0)

再次感谢BLUEPIXY,根据您的信息,我能够进行所需的更改,并能够在找到TP2的数据中提取数据,然后在等号后面提取数据。我确信有一种更好的方法来编写代码,但我的解决方案如下。我将添加一个更改,以便能够接受任何文件名和

的原因
MOP1Equal[strlen(MOP1Equal) -1] ='\0'; 

是为了将csv文件放入excel和

fprintf(file2, "\t%s", MOP1Equal+1); 

我添加1是为了摆脱=符号。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#define MAX_LINE_LENGTH 150

int main(void) {

FILE *file1, *file2;
char parts[MAX_LINE_LENGTH+1] = "startingvaluebeforechange";

char TP2[4] = "TP2";
char DP3[4] = "DP3";
char MOP1[4] = "OP1";
char MOP2[4] = "OP2";
char Equal[2] = "=";

char TP2Temp[MAX_LINE_LENGTH];
char TP2Equal[MAX_LINE_LENGTH];

char DP3Temp[MAX_LINE_LENGTH];
char DP3Equal[MAX_LINE_LENGTH];

char MOP1Temp[MAX_LINE_LENGTH];
char MOP1Equal[MAX_LINE_LENGTH];

char MOP2Temp[MAX_LINE_LENGTH];
char MOP2Equal[MAX_LINE_LENGTH];

file1 = fopen("input.txt", "r");
file2 = fopen("output.txt", "w");

if (file1 == NULL || file2 ==NULL) {
    exit(1);
}

while(fgets(parts, sizeof(parts), file1)!=NULL){
    int len = strlen(parts);
    if(parts[len -1 ] =='\n'){
        parts[len -1 ] ='\0';
    }
    if(strstr(parts, TP2)!=NULL){
        strcpy(TP2Temp, strstr(parts,TP2));
        strcpy(TP2Equal, strstr(TP2Temp,Equal));
        TP2Equal[strlen(TP2Equal) -2] ='\0';            
        fprintf(file2, "%s", TP2Equal+2);
    }
    if(strstr(parts,DP3)!=NULL){
        strcpy(DP3Temp, strstr(parts,DP3));
        strcpy(DP3Equal, strstr(DP3Temp,Equal));
        DP3Equal[strlen(DP3Equal) -1] ='\0';
        fprintf(file2, "\t%s", DP3Equal+1);
    }
    if(strstr(parts, MOP1)!=NULL){
        strcpy(MOP1Temp, strstr(parts,MOP1));
        strcpy(MOP1Equal, strstr(MOP1Temp,Equal));
        MOP1Equal[strlen(MOP1Equal) -1] ='\0';
        fprintf(file2, "\t%s", MOP1Equal+1);
    }
    if(strstr(parts, MOP2)!=NULL){
        strcpy(MOP2Temp, strstr(parts,MOP2));
        strcpy(MOP2Equal, strstr(MOP2Temp,Equal));
        fprintf(file2, "\t%s", MOP2Equal+1);
    }
}
fclose(file1);
fclose(file2);
return 0;

}