我有一个包含以下内容的输入文件:
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;
行,因为在此之前它会读出正确的字样。
提前致谢。
答案 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;
}
}
}
记忆。