首页 > 解决方案 > C 编程 - 无法使用指针将字符串从缓冲区复制到给定的字符数组

问题描述

我不确定我在哪里搞砸了,所以我给出了每个函数的摘要,以便可以检查我的逻辑!

主程序从命令行获取参数并将它们存储在 char 指针数组中。

运行程序的正确命令是 ./re-do_hw4_prob6 文件名。(在这种情况下,文件名是 sears_kmart_stores_closing_2019.txt)

检查参数编号是否正确后,打开文件。

while 循环将文本字符串从文件复制到缓冲区,直到遇到 NULL。

然后调用函数 getState()。打印状态。

文件已关闭。

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

#include "redo_hw4_functs.h"


int main(int argc, char* argv[])
{
    char** states;
    FILE* pFile;
    char buffer[80];
    int i = 0;
    
    
    
    if(argc < 2){
        printf("Too few arguments! \n");
    }
    else if(argc > 2){
        printf("Too many arguments! \n");
    }
    
   
    pFile = fopen(argv[1], "r");
    
    states = malloc(50*sizeof(char));
    
    for (i = 0; i < 50; i++)
    {
    states[i] = malloc(3*sizeof(char));
    
    while(fgets(buffer, sizeof(buffer), pFile) != NULL)
    {
        
        getState(states[i], buffer);
        
        printf("State: %s \n", states[i]);
        
    }
        
        
        }
    
    
    
    fclose(pFile);
    
}

getState() 函数接受两个字符数组。一个也可以从另一个读取复制。

它使用逗号、制表符和新行作为分隔符来标记正在读取的字符串。-> ",\t\n"

在最后一个标记上,它将最后两个字符复制到空字符串数组。

//accepts a line of string formatted as expected and stores the store state in char file ¡OJO! This is the hardest one because you cant rely on delimeters alone to find state 
void getState(char strState[], char strLine[])
{
    int i;
    char* token;
    char delim[] = ",\t\n";
    
    token = strtok(strLine, delim);
    token = strtok(strLine, delim);
    token = strtok(strLine, delim);
    
    for(i = (strlen(token) - 2); i < strlen(token); i++)
    {
        strState[i] =token[i];
    }
    
}

我还包括了我的其他功能,看看是否还有其他错误需要纠正。

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


#include "redo_hw4_functs.h"



//accepts a line of string formatted as expected and stores the store name in char file
void getName(char strName[], char strLine[])
{
    char* token;
    char delim[] = " ,\t\n";
    
    token = strtok(strLine, delim);
    
    while(token != NULL)
    {
        if(strcmp(token, "sears") == 0 || strcmp(token, "kmart"))
        {
            strcpy(strName, token);
            break;
        }
        
        token = strtok(NULL, delim);
    }
    
    
    
    
}

//accepts a line of string formatted as expected and stores the store address in char file
void getAddress(char strAddress[], char strLine[])
{
    
    char* token;
    char delim[] = ",\t\n";
    
    token = strtok(strLine, delim);
    
    while(token != NULL)
    {
        if(isdigit(token[0]) && isalpha(token[sizeof(token)-1]))
        {
            strcpy(strAddress, token);
            break;
        }
        
        token = strtok(NULL, delim);
    }
    
}

//accepts a line of string formatted as expected and stores the store city in char file
void getCity(char strCity[], char strLine[])
{
    int i;
    char* token;
    char delim[] = ",\t\n";
    
    token = strtok(strLine, delim);
    token = strtok(strLine, delim);
    token = strtok(strLine, delim);
    
    for(i = 0; i < (strlen(token) - 3); i++)
    {
        strcpy(strCity[i], token[i]);
    }
    
    
    
    
    
    
}

//accepts a line of string formatted as expected and stores the store state in char file ¡OJO! This is the hardest one because you cant rely on delimeters alone to find state 
void getState(char strState[], char strLine)
{
    int i;
    char* token;
    char delim[] = ",\t\n";
    
    token = strtok(strLine, delim);
    token = strtok(strLine, delim);
    token = strtok(strLine, delim);
    
    for(i = (strlen(token) - 2); i < strlen(token); i++)
    {
        strcpy(strState[i], token[i]);
    }
    
}

以下是要读取的输入文本示例:

Kmart, 217 Forks Of River Pkwy, Sevierville TN
Kmart, 4110 E Sprague Ave, Spokane WA
Kmart, 1450 Summit Avenue, Oconomowoc WI
Sears, 2050 Southgate Rd, Colorado Spgs CO
Sears, 1650 Briargate Blvd, Colorado Spgs CO
Sears, 3201 Dillon Dr, Pueblo CO

以下是程序预期输出的示例:

州:TN 州:WA 州:WI 州:CO 州:CO 州:CO

这是程序输出的示例:

在此处输入图像描述

标签: cstrtok

解决方案


我假设您不仅需要状态,还需要所有其他字段,以便以后处理它们。

下面的代码可能与您的代码有很大不同,但我认为使用单个函数读取每条记录更容易。

该函数read_data()从文件指针中读取数据fp并将它们存储在data,这是一个指向预定义结构的指针data_t

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

#define BUFFER_SIZE 1024

typedef struct {
    char name[64];
    char addr[64];
    char city[64];
    char state[8];
} data_t;

int read_data(FILE *fp, data_t *data) {
    char buffer[BUFFER_SIZE];

    // Read a record. If end-of-file is read, return -1.
    if (fgets(buffer, BUFFER_SIZE, fp) == NULL) {
        return -1;
    }

    char delim[] = ",\t\n";

    // Find the name of the record.
    char *token = strtok(buffer, delim);
    strcpy(data->name, token);

    // Find the address of the record.
    token = strtok(NULL, delim);
    while (*token == ' ') {
        ++token;
    }
    strcpy(data->addr, token);

    // Find the city and status of the record.
    // We cannot split them by strtok() easily, so we handle it later.
    token = strtok(NULL, delim);
    while (*token == ' ') {
        ++token;
    }

    // Find the position of the state.
    char *ptr = token;
    while (*ptr != '\0') {
        ++ptr;
    }
    ptr -= 2;
    strcpy(data->state, ptr);

    // Use NULL to separate the city and the state so that we can use strcpy().
    while (*(ptr - 1) == ' ') {
        --ptr;
    }
    *ptr = '\0';

    // Copy the city field.
    strcpy(data->city, token);
    return 0;
}

int main(int argc, char *argv[]) {
    if (argc != 2) {
        fprintf(stderr, "The number of arguments is incorrect.\n");
        fprintf(stderr, "Usage: %s filename\n", argv[0]);
        return -1;
    }
    FILE *fp = fopen(argv[1], "r");
    data_t *data = malloc(sizeof(data_t));
    while (read_data(fp, data) == 0) {
        printf("State: %s\n", data->state);
    }
    free(data);
    fclose(fp);
    return 0;
}

读取数据的方式是硬编码的,因此如果输入格式不同,可能需要更改 的内容read_data(),但它适用于您的示例输入。


推荐阅读