逐行读取空格分隔字符串并在数组中存储它们(在C中)

时间:2016-10-26 09:09:47

标签: c

我有一个包含以下内容的输入文件:

CREATEHALL "Red-Hall" "StarDust" 24 20
CREATEHALL "Orange-Hall" "Last_Samurai" 10 20

我想将每一行存储在数组中以供将来使用。

目前我的代码是: (为了调试目的,添加了许多printf。)

#include <stdio.h>
#include <stdlib.h>
struct str
{
char *commands[5];
};

struct str a[];
int main()
{
    int i=0;
    int j=0;
    char *token;
    printf("Starting the program...\n");
    char filename[] = "input.txt";
    FILE *file = fopen ( filename, "r" );

    if (file != NULL) {
        char line [1000];
        printf("Read a new line...\n");
        while(fgets(line,sizeof line,file)!= NULL) /* read a line from a file */ {
            j=0;
            printf("%s\n",line);
            printf("Start token stuff...\n");
            /* get the first token */
            token = strtok(line, " ");

            /* walk through other tokens */
            while( token != NULL )
            {
                a[i].commands[j]=token;
                printf( "Stored Command : %s\n", token );
                token = strtok(NULL, " ");
                j++;
            }
            i++;
        }

        fclose(file);
    }
    else {
        perror(filename); //print the error message on stderr.
    }
    printf("Finished processing tokens...\n\n\n");

    printf("%s\n%s\t%s\t%s\t%s\n", a[0].commands[0], a[0].commands[1],a[0].commands[2],a[0].commands[3],a[0].commands[4]);
    printf("%s\n%s\t%s\t%s\t%s\n", a[1].commands[0], a[1].commands[1],a[1].commands[2],a[1].commands[3],a[1].commands[4]);
    return 0;
}

我在控制台上获得的输出是:

Starting the program...
Read a new line...
CREATEHALL "Red-Hall" "StarDust" 24 20

Start token stuff...
Stored Command : CREATEHALL
Stored Command : "Red-Hall"
Stored Command : "StarDust"
Stored Command : 24
Stored Command : 20

CREATEHALL "Orange-Hall" "Last_Samurai" 10 20
Start token stuff...
Stored Command : CREATEHALL
Stored Command : "Orange-Hall"
Stored Command : "Last_Samurai"
Stored Command : 10
Stored Command : 20
Finished processing tokens...


CREATEHALL
"Orange-Hall"   l"      murai"  ai"
CREATEHALL
"Orange-Hall"   "Last_Samurai"  10      20

我对C不太好(这是作业的一小部分)但我相信错误在

a[i].commands[j]=token;

行,因为在此之前它会读出正确的字样。

提前致谢。

2 个答案:

答案 0 :(得分:1)

正如@LP建议的那样,只需添加一个strdup()调用,以便在存储到数组中时保留提取的字符串。但在此之前,请确保您已将struct str分配给[];

Step1替换:

<UIGestureRecognizerDelegate>

由:

struct str a[];

Step2在存储到数组中时添加strdup():

#define MAX_NB_LINES (100)
struct str a[MAX_NB_LINES];
  

在开始使用struct str a []之前,将char指针初始化为   NULL。

while( token != NULL )
{
    a[i].commands[j]=strdup(token);
    printf( "Stored Command : %s\n", token );
    token = strtok(NULL, " ");
    j++;
    if (j >= 5) break; // stop extraction when 5 commands are stored
}
  

使用struct str a []后,只需释放已分配的内存即可。

for(i=0;i<MAX_NB_LINES;i++) {
    for(j=0;j<5;j++) {
        a[i].commands[j]=NULL;
    }
}

答案 1 :(得分:0)

来自the Man

  

返回值

     

strtok()和strtok_r()函数返回指向下一个标记的指针,如果没有更多标记,则返回NULL。

您存储的指针是struct str a[]; 的地址,在您的流程结束时,它将包含最后一行读取。

另请注意,您定义了一个没有维度的错误数组:

struct str a[2];

至少应该是

#define _BSD_SOURCE

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

struct str
{
char *commands[5];
};

struct str a[2];
int main()
{
    int i=0;
    int j=0;
    char *token;
    printf("Starting the program...\n");
    char filename[] = "input.txt";
    FILE *file = fopen ( filename, "r" );

    if (file != NULL) {
        char line [1000];
        printf("Read a new line...\n");
        while(fgets(line,sizeof line,file)!= NULL) /* read a line from a file */ {
            j=0;
            printf("%s\n",line);
            printf("Start token stuff...\n");
            /* get the first token */
            token = strtok(line, " ");

            /* walk through other tokens */
            while( token != NULL )
            {
                char *temp = strdup(token);
                if (temp != NULL)
                {
                    a[i].commands[j]=temp;
                }
                else
                {
                    fprintf(stderr, "No memory available to store string\n");
                    return 1;
                }
                printf( "Stored Command : %s\n", token );
                token = strtok(NULL, " ");
                j++;
            }
            i++;
        }

        fclose(file);
    }
    else {
        perror(filename); //print the error message on stderr.
    }
    printf("Finished processing tokens...\n\n\n");

    printf("%s\n%s\t%s\t%s\t%s\n", a[0].commands[0], a[0].commands[1],a[0].commands[2],a[0].commands[3],a[0].commands[4]);
    printf("%s\n%s\t%s\t%s\t%s\n", a[1].commands[0], a[1].commands[1],a[1].commands[2],a[1].commands[3],a[1].commands[4]);
    return 0;
}

最快的修正可以是:

free

在更复杂的项目中,由于strdup执行堆分配,重复字符串必须为#include <stdio.h> #include <stdlib.h> #include <string.h> struct str { char *commands[5]; }; struct str a[2]; int main() { int i=0; int j=0; char *token; printf("Starting the program...\n"); char filename[] = "input.txt"; FILE *file = fopen ( filename, "r" ); if (file != NULL) { char line [1000]; printf("Read a new line...\n"); while(fgets(line,sizeof line,file)!= NULL) /* read a line from a file */ { j=0; printf("%s\n",line); printf("Start token stuff...\n"); /* get the first token */ token = strtok(line, " "); /* walk through other tokens */ while( token != NULL ) { a[i].commands[j] = malloc(strlen(token)+1); if (a[i].commands[j] != NULL) { strcpy(a[i].commands[j], token); } else { fprintf(stderr, "No memory available to store string\n"); return 1; } printf( "Stored Command : %s\n", token ); token = strtok(NULL, " "); j++; } i++; } fclose(file); } else { perror(filename); //print the error message on stderr. } printf("Finished processing tokens...\n\n\n"); printf("%s\n%s\t%s\t%s\t%s\n", a[0].commands[0], a[0].commands[1],a[0].commands[2],a[0].commands[3],a[0].commands[4]); printf("%s\n%s\t%s\t%s\t%s\n", a[1].commands[0], a[1].commands[1],a[1].commands[2],a[1].commands[3],a[1].commands[4]); return 0; }

可以使用malloc实现另一个解决方案,并为每个元素分配空间,并使用strcpy复制令牌。

free

在这里,你应该malloc d public class Statistics { private readonly IConnectionFactory connectionFactory; private readonly IConnection connection; private readonly ISession session; public Statistics( string brokerUri) { this.connectionFactory = new ConnectionFactory(brokerUri); this.connection = connectionFactory.CreateConnection(); this.connection.Start(); this.session = connection.CreateSession(); } public void GetStats() { // Crear consumidor try { // Creo una cola y consumidor IDestination queueReplyTo = session.CreateTemporaryQueue(); IMessageConsumer consumer = session.CreateConsumer(queueReplyTo); // Crear cola monitorizada string listeningQueue = "TEST1"; ActiveMQQueue testQueue = session.GetQueue(listeningQueue); // Crear cola y productor ActiveMQQueue query = session.GetQueue("ActiveMQ.Statistics.Destination.TEST1"); IMessageProducer producer = session.CreateProducer(null); // Mandar mensaje vacío y replicar IMessage msg = session.CreateMessage(); producer.Send(testQueue, msg); msg.NMSReplyTo = queueReplyTo; producer.Send(query, msg); // Recibir IMapMessage reply = (IMapMessage)consumer.Receive(); if (reply != null) { IPrimitiveMap statsMap = reply.Body; foreach (string statKey in statsMap.Keys) { Console.WriteLine("{0} = {1}", statKey, statsMap[statKey]); } } } catch (Exception e) { var t = e.Message + " " + e.StackTrace; } } } 记忆。