使用指针从csv文件复制一行 [英] Copying a line from a csv file using pointers

查看:82
本文介绍了使用指针从csv文件复制一行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm writing a program that is supposed to search for a name in a CSV file and copy the record (all the info on the same line as the name) that goes along with it.

例如,如果CSV文件包含:

For example, if CSV file contains:

Bob, 13, 12345612
Eli, 12, 21398743

我将输入"Bob"以获得第一行,并将其复制到名为"record"的数组中.

I would input "Bob" to get the first line, and copy this into an array called "record".

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

So far my code is as follows:

#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)并复制行的其余部分.一旦找到该单词,我就一直尝试使用该单词的长度,但这由于指针而无法正常工作.任何帮助/提示将不胜感激.

Basically, I've found Bob and copied Bob, but do not understand how to proceed using pointers (not allowed to use string.h) and copying the rest of the line. I've been trying to play around with the length of the word once Ive found it but this isn't working either because of pointers. Any help/hints would be appreciated.

推荐答案

不允许使用string.h是手动计算字符串长度的好方法(必须从用<读取的行中删除尾随'\n' c4>),也是手动进行字符串比较的不错的练习.

Not being allowed to use string.h is a good exercise in computing the string lengths manually (necessary to remove the trailing '\n' from the lines read with fgets) and also a good exercise for manual string comparisons.

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

For example, if you are reading lines into buf, you can use a simple for loop to get the length of buf, e.g.

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

(注意:,您发现name的长度,以类似的方式说nlen)

(note: you find the length of name, say nlen in a similar manner)

然后具有blen中的长度,您可以轻松地检查buf中的最后一个字符是否为'\n'字符,并通过使用 nul-terminate 字符覆盖换行符来将其删除,例如

Then having the length in blen, you can easily check that the final character in buf is the '\n' character and remove it by overwriting the newline with the nul-terminating character, e.g.

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

findrecord函数的其余部分仅是向前迭代每个字符以查找作为name中第一个字符的字符的问题.找到后,您只需比较下一个nlen字符以查看是否在buf中找到了name.您可以轻松地做到这一点:

The remainder of your findrecord function is just a matter of iterating forward over each character looking for the character that is the first character in name. Once found, you simply compare then next nlen character to see if you have found name in buf. You can easily do that with:

            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)) {

您已经确认自己在buf中找到了name,只需将buf复制到record,以确保在复制完buf后使用 nul-terminate record,例如

One you have validated you found name in buf, simply copy buf to record insuring your nul-terminate record when done copying buf, e.g.

            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 */
            }

将其放在一起,您可以执行以下操作:

Putting it altogether, you could do something similar to the following:

#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'

非匹配示例

$ ./bin/findrec dat/bob.csv
Please input a name in the phonebook: Jerry
Please input a replacement name: Bob

仔细检查一下,如果还有其他问题,请告诉我.

Look things over and let me know if you have further questions.

这篇关于使用指针从csv文件复制一行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆