我有一个名为2列的csv文件;时间戳,SNR(int值)。我必须编写一个首先询问用户输入的函数;用户想要的价值? 样本文件:
timestamp ; SNR
16:15:12:468 ; 15
16:15:12:968 ; 20
例如:如果我输入 SNR ,该功能应该给我列号。 SNR; (这是第2列)以及SNR的值。
Output : Col. no. is 2
15 /* time difference of ((16:15:12:968)-(16:15:12:458) = 500ms between these two output values*/
20
但是这些值应该在某个时间间隔内作为输出给出。这意味着必须首先读取时间戳列,并且应该计算两个时间戳(当前和下一个)值之间的差值。现在应该在这两个时间戳值之间的差值区间上给出SNR作为输出。我不想使用数组或结构,因为我不想存储值;我只是要求这些值在特定时间间隔内传递给其他应用程序。
我写了以下代码。我可以获取用户输入并输出列号。的文件,但我无法获得这些列的内容。我在我的程序中使用了开关盒,但我不知道为什么这个开关盒不起作用。我还编写了一个函数来获取这两个时间戳之间的时差,但是我没有得到如何在这个函数中将它组合起来。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
#include <time.h>
#define BUFFER_SIZE 1024
#define num_rows 100
const char* gettime(char* line, int num )
{
const char* tok;
for (tok = strtok(line, ";");tok && *tok;tok = strtok(NULL, ";\n"))
{
if (!num--)
//Sleep(500);
return tok;
}
return NULL;
}
const char* getSNR(char* line, int num )
{
const char* tok;
for (tok = strtok(line, ";");tok && *tok;tok = strtok(NULL, ";\n"))
{
if (!num--)
//Sleep(500);
return atoi(tok);
}
return NULL;
}
struct tm mytime;
int main ()
{
int hh, mm;
float ss, ms;
mytime.tm_year = 2015 - 1900; /* To initialize the struct tm*/
mytime.tm_mon = 6;
mytime.tm_mday = 15;
int count;
int value;
char text[25];
char *buffer;
FILE *fp;
char *token;
char *tok;
char line [100];
char time_buffer[100];
char **timestamp; /*Dynamic allocated array*/
unsigned long ul_second_prev ;
unsigned long ul_second_current;
int i=0, j=0, k=1;
int ui_time_diff, ui_SNR;
time_t time_prev, time_current; /*Dynamic allocated array*/
int timediff ;
timestamp = malloc(num_rows*sizeof(char*));
if ((timestamp)== NULL)
{
printf("Error: out of memory");
}
if ((fp=fopen("testfile.csv", "r"))==NULL)
{
printf ("file cannot be opened");
return 1;
}
buffer = malloc (BUFFER_SIZE); /*Allocate memory in buffer to read the file*/
if (buffer == NULL)
{
printf("Error: Out of Memory");
return 1;
}
fgets(line, BUFFER_SIZE, fp);
printf ("%s", line);
printf ("enter your input\n");
scanf("%s" , &text);
for (tok = strtok(line, ";");tok && *tok;tok = strtok(NULL, ";\n"))
{
value = strcmp (tok, text);
if(value ==0)
printf("col. no. is %d", k);
else k++ ;
}
while (fgets(line, BUFFER_SIZE, fp))
{
char* tmp = strdup(line);
switch (k)
{
case 1:
gettime(tmp, 1);
printf ( "%s",tok );
break;
case 2:
getSNR(tmp, 2);
printf ( "%s",tok );
break;
}
free(tmp);
}
答案 0 :(得分:2)
除了大量未使用的变量和至少一个未使用的包含(<windows.h>
)之外,gcc还提供了这些警告,可能指出了您的问题:
> gcc -std=c99 -Wall -Wextra -pedantic -oq q.c
q.c: In function ‘getSNR’:
q.c:26:9: warning: return makes pointer from integer without a cast
return atoi(tok);
^
q.c: In function ‘main’:
q.c:84:5: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘char (*)[25]’ [-Wformat=]
scanf("%s" , &text);
^
q.c:96:5: warning: implicit declaration of function ‘strdup’ [-Wimplicit-function-declaration]
char* tmp = strdup(line);
^
q.c:96:17: warning: initialization makes pointer from integer without a cast
char* tmp = strdup(line);
^
q.c:110:1: error: expected declaration or statement at end of input
}
^
您的getSNR()
返回一个整数,但声明为返回一个字符指针(又名:string)。您放弃了返回值,只需将(未初始化的!)char *tok
(应该是const
以获取返回值)提供给%s
格式说明符。
在scanf
中,除了使用错误的指针类型(警告的内容)之外,还有缓冲区溢出。欢迎破解者。 永远不会使用scanf("%s", ...)
,没有方式来判断它将读取多少数据。在这种情况下使用fgets(text, 25, stdin)
。
编程C时你应该学习两件事:第一,准确而精确,而不是不稳定。其次,让你的编译器警告一切(必要时使用适当的开关)。编译器警告在98%的情况下意味着编程错误或错误。
话虽如此,拥有两个几乎相同的功能是愚蠢的。做这样的事情:
const char* getfield(char* line, int num )
{
const char* tok;
for (tok = strtok(line, ";");tok && *tok;tok = strtok(NULL, ";\n"))
{
if (!num--)
return tok;
}
return NULL;
}
这个循环还是有点奇怪,但这是一个风格问题......然后(注意你实际上指定从你的函数返回的值):
while (fgets(line, BUFFER_SIZE, fp))
{
switch (k)
{
case 1:
tok = getfield(line, 1);
printf ( "%s",tok );
break;
case 2:
tok = getfield(line, 2);
printf ( "%d",atoi(tok) );
break;
}
}
另请注意,您使用的已分配tmp
没有任何意义,因为您的line
缓冲区无论如何都会在循环的下一次迭代中被覆盖。那么为什么要复制一份?