在C

时间:2015-07-27 12:49:06

标签: c csv

我有一个名为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);
}

1 个答案:

答案 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缓冲区无论如何都会在循环的下一次迭代中被覆盖。那么为什么要复制一份?