使用指针从csv文件复制一行

时间:2017-11-06 04:35:57

标签: c pointers

我正在编写一个程序,该程序应该在CSV文件中搜索名称并复制记录(与名称在同一行上的所有信息)。

例如,如果CSV文件包含:

Bob, 13, 12345612
Eli, 12, 21398743

我会输入"Bob"来获取第一行,然后将其复制到名为"record"的数组中。

到目前为止,我的代码如下:

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

void FindRecord(char *a, char *b, char c[]);

void main(void){

    char arrayName[100];
    char arrayNewname[100];
    char *name = arrayName;
    char *newname = arrayNewname;
    char record[1000];

    printf("Please input a name in the phonebook: ");
    scanf("%s", name);

    printf("Please input a replacement name: ");
    scanf("%s", newname);

    FindRecord("phonebook.csv",name,record);
    }

    void FindRecord(char *filename, char *name, char record[]){

    //Create temp array of max size 
    char temp[1000];

    //Open file
    FILE *f = fopen(filename, "r");
    //Make sure file exists 
    if (f == NULL){
        printf("File does not exist");
        fclose(f);
        exit(1);
    }

    //While 
    while(!feof(f)){
        //Read one line at a time   
        fgets(temp, 1000, f); 
        int i = 0;
        int *p;
        for(int i = 0; i < 1000; i++){
            if(temp[i] == *name){
                record[i] = temp[i];
                name++;
            }
            size_t n = (sizeof record /sizeof record[0]);
            if(temp[i] == *name){
            *p = temp[i + n];
            }
        }
    }   
    printf("%s", record);
    fclose(f);
}

基本上,我找到了Bob并复制了Bob,但是不明白如何继续使用指针(不允许使用string.h)并复制其余部分。一旦我找到它,我一直试着玩这个词的长度,但这也不是因为指针而起作用。任何帮助/提示将不胜感激。

2 个答案:

答案 0 :(得分:0)

如果不允许使用string.h,则必须通过char比较字符串char。 首先要有一个循环来查找名称。

请参阅:Compare two strings character by character in C

然后复制剩下的记录。 char by char或更高级的函数,如memcpyhttps://www.techonthenet.com/c_language/standard_library_functions/string_h/memcpy.php

现在谁是int *p

你没有初始化这个指针。您必须对其进行malloc或将其分配给现有内存。 有关更多信息,请参阅 https://pebble.gitbooks.io/learning-c-with-pebble/content/chapter08.html

我认为你应该阅读更多有关指针的内容,然后事情会对你有所帮助。

答案 1 :(得分:0)

不允许使用string.h是一个很好的练习,可以手动计算字符串长度(从'\n'读取的行中删除尾随的fgets),也是一个很好的练习用于手动字符串比较。

例如,如果您正在阅读buf行,则可以使用简单的for循环来获取buf的长度,例如

    int blen = 0;
    for (; buf[blen]; blen++) {}        /* get line length */

注意:您找到name的长度,以类似的方式说nlen

然后使用blen中的长度,您可以轻松检查buf中的最后一个字符是'\n'字符,并通过使用 nul覆盖换行符来删除它终止字符,例如

    if (blen && buf[blen - 1] == '\n')  /* check/remove '\n' */
        buf[--blen] = 0;                /* overwrite with '\0' */

findrecord函数的其余部分只是在每个字符上向前迭代,寻找name中第一个字符的字符。找到后,您只需比较下一个nlen字符,看看您是否在name中找到了buf。您可以通过以下方式轻松完成:

            char *np = name,            /* pointer to name */
                *bp = p;                /* current pointer in buf */
            ...
            for (i = 0;     /* compre name in buf */
                i < nlen && *np && *bp && *np == *bp; 
                i++, np++, bp++) {}
            /* validate nlen chars match in buf */
            if (np - name == nlen && *(np-1) == *(bp-1)) {

您已在name中验证了buf的{​​{1}},只需将buf复制到record即可确保 nul-terminate {{1}完成复制record时,例如

buf

完全放弃,你可以做类似以下的事情:

            if (np - name == nlen && *(np-1) == *(bp-1)) {
                bp = buf;
                for (i = 0; buf[i]; i++)    /* copy buf to record */
                    record[i] = buf[i];
                record[i] = buf[i];         /* nul-terminate */
                return record;              /* return record */
            }

示例使用/输出

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

enum { MAXC = 100, MAXL = 1000 }; /* if you need constants, define them */

char *findrecord (FILE *fp, char *name, char *record);

/* main is type 'int', and has arguments -- use them */
int main (int argc, char **argv) {

    char name[MAXC] = "",
        replace[MAXC] = "",
        record[MAXL] = "",
        *matched;
    FILE *fp = argc > 1 ? fopen (argv[1], "r") : NULL;

    if (!fp) {  /* validate file open for reading */
        fprintf (stderr, "error: file open failed '%s'.\n", argv[1]);
        return 1;
    }
    /* prompt, read, validate name */
    printf ("Please input a name in the phonebook: ");
    if (scanf ("%99[^\n]%*c", name) != 1) {
        fprintf (stderr, "error: invalid input - name.\n");
        return 1;
    }
    /* prompt, read, validate replace */
    printf("Please input a replacement name: ");
    if (scanf ("%99[^\n]%*c", replace) != 1) {
        fprintf (stderr, "error: invalid input - replace.\n");
        return 1;
    }
    /* search name, copy record, return indicates success/failure */
    matched = findrecord (fp, name, record);
    if (fp != stdin) fclose (fp);   /* close file if not stdin */

    if (matched) {  /* if name matched */
        printf ("record : '%s'\n", record);
    }

    return 0;   /* main() returns a value */
}

char *findrecord (FILE *fp, char *name, char *record){

    char buf[MAXL] = "";                /* buf for line */

    while (fgets (buf, MAXL, fp)) {     /* for each line */
        char *p = buf;
        int blen = 0;
        for (; buf[blen]; blen++) {}        /* get line length */
        if (blen && buf[blen - 1] == '\n')  /* check/remove '\n' */
            buf[--blen] = 0;                /* overwrite with '\0' */
        for (; *p && *p != '\n'; p++)       /* for each char in line */
            if (*p == *name) {              /* match start of name? */
                char *np = name,            /* pointer to name */
                    *bp = p;                /* current pointer in buf */
                int i = 0,                  /* general 'i' var */
                    nlen = 0;               /* name length var */
                for (nlen = 0; name[nlen]; nlen++) {}   /* name length */
                for (i = 0;     /* compre name in buf */
                    i < nlen && *np && *bp && *np == *bp; 
                    i++, np++, bp++) {}
                /* validate nlen chars match in buf */
                if (np - name == nlen && *(np-1) == *(bp-1)) {
                    bp = buf;
                    for (i = 0; buf[i]; i++)    /* copy buf to record */
                        record[i] = buf[i];
                    record[i] = buf[i];         /* nul-terminate */
                    return record;              /* return record */
                }
            }
    }

    return NULL;    /* indicate no match in file */
}

非匹配示例

$ ./bin/findrec dat/bob.csv
Please input a name in the phonebook: Bob
Please input a replacement name: Sam
record : 'Bob, 13, 12345612'

仔细看看,如果您有其他问题,请告诉我。