2

Quite new to C so apologies for the long read and no doubt rubbish programming.

So my program is reading in a CSV file, containing the specification of 15 different transistors. It then compares an input to the data from the CSV file. After the data is input, the program determines which transistors are most suitable. This is meant to loop until the letter q is entered, which is when the program is meant to stop.

The input is entered as eg.

10 0.05 120 5000 20

for volt, amp, power, freq and gain respectively. The program doesn't care about type, company or price.

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#define MAX 15
#define MAX_IN 10000

struct data{
char type[10], company[10];
int volt, power, freq, gain;
float amp, price;
};

struct input{
int volt, power, freq, gain;
float amp;
};
struct input inputs[MAX_IN];
struct data datas[MAX];


main()
{
    int chk = 1, num=0;
    while(chk == 1)
    {
        chk = input_function(&num);
    }
}

int input_function(int *number)
{
    int j=0;
    char check=0;

    scanf("%c%d %f %d %d %d", &check, &inputs[j].volt, &inputs[j].amp, inputs[j].power, &inputs[j].freq, &inputs[j].gain);

    if(check!='q')
    {
        check_function(j);
        ++*number;
        ++j;
        return 1;
     }
     else
     {
        return 0;
     }
}

num is an integer used to determine how many inputs I have put in so that the check function compares the correct input for the input structure.

In a previously similar problem, using %c%d let it check for both a character and an integer at the same time, but this isn't working.

Previously I had it almost working, but it took q as the first input to voltage - so every input after was off by one. Anyone have any ideas?

  • 1
    If you get your input with `fgets` you can examine the string at your leisure. Don't forget the trailing `newline` it retains. Once you establish it is not a quit, apply `sscanf`. – Weather Vane Mar 30 '17 at 16:08
  • 4
    Alternatively, you should be checking the return value from `scanf` anyway (5 if you remove the `%c`). If the first character is `'q'` then the integer conversion will be refused, and the `'q'` remains in the input buffer. But you also need to consider the commas: you say they are CSV files. In which case I would use `fgets` and `strtok` or its reentrant version. – Weather Vane Mar 30 '17 at 16:11
  • When I use fgets it doesn't prompt for any input? How should I do this? – user7604801 Mar 30 '17 at 16:23
  • 1
    I don't understand you. The program has no input prompt anyway. – Weather Vane Mar 30 '17 at 16:27
  • 2
    `scanf(" %c", &check); if(check!='q'){ ungetc(check, stdin); scanf("%d %f %d %d %d", &inputs[j].volt, ...`. Also `int j=0;` --> `int j = *number;` – BLUEPIXY Mar 30 '17 at 16:33
  • That is exactly what I needed thank you – user7604801 Mar 30 '17 at 16:40

1 Answers1

3

scanf, fscanf, and sscanf are broken-as-specified and shouldn't ever be used for anything. Forget you ever heard of them.

Use fgets (or getline if available) to read the entire line. Examine its first character manually. If it is q, exit. Otherwise, use a chain of calls to strtol and strtod to parse the line and convert text to machine numbers. (Pay close attention to the part of the strtol/strtod manpages where they explain how to check for errors; it's a little tricky.)

zwol
  • 135,547
  • 38
  • 252
  • 361