逐行读取文件,并将逗号分隔的每个字符扫描到C中的单独变量中

时间:2018-11-17 06:57:13

标签: c file-io

必须读取具有以下格式的file.txt: 12AA,abc12 \ n 4CCC,cde15 \ n

我想逐行读取文件并将逗号分隔的值存储在单独的变量中。

fp = fopen("file.txt", "r");

while(fgets(buffer, 255, (FILE*) fp)) 
{
    fscanf(fp, "%s %s", acc_no, package);
    printf("%s\n", acc_no);
    printf("%s\n", package);
}

fclose(fp);

我不仅要读取和打印变量,还要将它们存储在单独的变量中。有关如何操作的建议?

2 个答案:

答案 0 :(得分:3)

strchr()可以帮助您:

while (fgets(str, sizeof str, fp)) {
    char *arr[2], *ptr;

    arr[0] = str;
    if ((ptr = strchr(str, ','))) {
        arr[1] = ptr + 1;
        *ptr = '\0';
    } else {
        exit(EXIT_FAILURE);
    }
    printf("<%s> <%s>\n", arr[0], arr[1]);
}

请注意,您可能需要删除fgets()留下的结尾换行符,或者省略\n中的printf

如果您需要将这些字符串存储在新的内存中,那么还有更多工作要做,您可以realloc()或使用链接列表(当您不知道行数时总是喜欢使用链接列表)预先):

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

struct node {
    void *data;
    struct node *next;
};

/* Returns a pointer to an allocated string */
extern char *strdup(const char *);

/* Insert a node and returns a pointer to the data */
static void *enqueue(struct node **root, void *data)
{
    struct node *node;

    if (root == NULL) {
        return NULL;
    }
    node = malloc(sizeof *node);
    if (node == NULL) {
        return NULL;
    }
    if (*root == NULL) {
        node->next = node;
    } else {
        node->next = (*root)->next;
        (*root)->next = node;
    }
    node->data = data;
    *root = node;
    return data;
}

/* Delete a node and returns a pointer to the data */
static void *dequeue(struct node **root)
{
    struct node *node;
    void *data = NULL;

    if (root == NULL) {
        return NULL;
    }
    node = *root;
    if (node != NULL) {
        node = node->next;
        data = node->data;
        if (*root == node) {
            *root = NULL;
        } else {
            (*root)->next = node->next;
        }
        free(node);
    }
    return data;
}

int main(void)
{
    struct node *head = NULL;
    char str[256];
    char **arr;
    char *ptr;

    /* While we don't hit EOF */
    while (fgets(str, sizeof str, stdin)) {
        /* Reserve space for 2 pointers */
        arr = malloc(sizeof(*arr) * 2);
        if (arr == NULL) {
            perror("malloc");
            exit(EXIT_FAILURE);
        }
        /* If we find a comma */
        if ((ptr = strchr(str, ','))) {
            /* Store the second string */
            arr[1] = strdup(ptr + 1);
            if (arr[1] == NULL) {
                perror("strdup");
                exit(EXIT_FAILURE);
            }
            /* Strip the string */
            *ptr = '\0';
        /* If we don't find a comma */
        } else {
            exit(EXIT_FAILURE);
        }
        /* Store the first string */
        arr[0] = strdup(str);
        if (arr[0] == NULL) {
            perror("strdup");
            exit(EXIT_FAILURE);
        }
        /* Add a node to the queue*/
        if (enqueue(&head, arr) == NULL) {
            perror("enqueue");
            exit(EXIT_FAILURE);
        }
    }
    /* While nodes in queue show the data and free */
    while ((arr = dequeue(&head))) {
        printf("%s %s", arr[0], arr[1]);
        free(arr[0]);
        free(arr[1]);
        free(arr);
    }
    return 0;
}

答案 1 :(得分:0)

您可以改用fscanf格式的字符串。

fscanf(fp, " %[^,\n], %[^\n]", values[i][0], values[i][1]);

喜欢

#include <stdio.h>

int main() {
    FILE* fp = fopen("file.txt", "r");

    char values[1000][2][100];

    int i = 0;
    while(!feof(fp)) {
      fscanf(fp, " %[^,\n], %[^\n]", values[i][0], values[i][1]);
      printf("%s %s\n", values[i][0], values[i][1]);
    }   

}

fscanf格式的字符串:

  • <space> =跳过前导空格(如前一行的换行符)
  • %[^,\n] =读取一个字符串,直到但不包括“,”或“ \ n”
  • , =期望逗号并将其丢弃
  • %[^\n] =读取一个字符串,直到但不包括“ \ n”

values是2D字符串数组,具有1000行2列。每个元素都是一个字符串,最大长度为100个字符。

此外,如果改为使用%m[^,\n],则fscanf将为读取的字符串分配内存。