-1

I am working on making a program that will take in an input parameter 'N' using argv. The value N will then allow the user to enter in N value of lines about a chemical element. For example, one line would look like

1 Hydrogen H other_nonmetals 1.008 1 0 0 0 0 0 0

and using a struct, I will scan and print the input in an organized matter.

I am having two main problems currently. The first problem is scanning in the electron values. In the Hydrogen example above, I would need to scan in 1 0 0 0 0 0 0 and reprint it out in my function print_element. When I do so, only the value 1 is stored. I want all the zeros to be omitted, but if the electron values were 1 0 0 0 0 0 1, then only the 1 would be printed in my function.

The next problem I am having is in my for loops. While looping the function print_element, an extra element with no values will be printed. For example, if the user inputs values for Hydrogen and then Barium, it will print Hydrogen then a completely blank element with all zeros, and then Barium. I cannot figure out how to get rid of the blank element.

#include <stdio.h>
#include <stdlib.h>
#define MAX_ELEMENTS 20

typedef struct{
  int num;
  char name[MAX_ELEMENTS];
  char symbol[MAX_ELEMENTS];
  char class[MAX_ELEMENTS];
  double weight;
  char electrons[MAX_ELEMENTS];
} element_t;

void scan_element(element_t *uno){
 scanf("%d %s %s %s %lf %20s", &uno->num, uno->name, uno->symbol, uno->class, &uno->weight, uno->electrons);
}

void print_element(element_t uno){
 printf("---------------\n| %d\t%.4f\n| %s\t%s\n| %s\n---------------\n", uno.num, uno.weight, uno.symbol, uno.name, uno.electrons);
}

int main (int argc, char *argv[]){
 int i;
 if (argc != 2){
     printf("ERROR: You must provide exactly one argument to this program.\n");
     return 0; }
 int N = (int)strtol(argv[1], NULL, 10);
 if(N <= 0){
     printf("ERROR: Your must provide an integer greater than 0 and less than or equal to 20.\n");
     return 0; }
 element_t uno[MAX_ELEMENTS];
 for(i=0; i<=argc; i++){
 scan_element(&uno[i]); }
 printf("%d total elements.\n", N);
 printf(" had the smallest atomic number.\n");
 printf(" had the largest atomic number.\n");
 for(i=0; i<=argc; i++){
     print_element(uno[i]); }
 return 0;
}
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Shaunbaum
  • 15
  • 5
  • You are using inconsistently indented [Pico-style](https://en.wikipedia.org/wiki/Indent_style#Pico_style) indentation. C is not Pico; please do not use that style. Use either Allman (I use that) or 1TBS (lots of people use that). It makes your code easier to read if you use a well-known style and are completely rigorous in handling indentation (which your code is not). – Jonathan Leffler Apr 11 '16 at 04:07
  • Your scanning loop is `for(i=0; i<=argc; i++){ scan_element(&uno[i]); }` but it should be `for (i = 0; i < N; i++) { scan_element(&uno[i]); }`. Note the different limit — `N` and `<` (instead of `argc` and `<=`). Your printing loop has the same problem. This could account for why there's an extra lot of input. You seem to be using `MAX_ELEMENTS` for too many things. There are elements up to 118 these days, but the name lengths are different, and the number of levels of electrons is different, etc. – Jonathan Leffler Apr 11 '16 at 04:11
  • Your test and error message don't match: `if(N <= 0){ printf("ERROR: Your must provide an integer greater than 0 and less than or equal to 20.\n"); return 0; }` — You should probably use: `if (N <= 0 || N > MAX_ELEMENTS){ fprintf(stderr, "ERROR: Your must provide an integer greater than 0 and less than or equal to %d.\n", MAX_ELEMENTS); return 1; }` (the `return 1` indicates a failure on most systems; use `EXIT_FAILURE` instead of 1 to be safe on all systems, and `stderr` is for reporting errors). – Jonathan Leffler Apr 11 '16 at 04:13

1 Answers1

0

Replace for(i=0; i<=argc; i++) with for(i=0;i<N;i++).

To omit the first 0 and everything after it in electrons, add

char*tmp;
if(tmp=strstr(uno->electrons," 0"))
    *tmp=0;

to scan_element.

It is faster if you only pass the pointer in print_element, because 4 or 8 bytes will be copied instead of 92.

It is not good to use your current way to get string from input. See How to prevent scanf causing a buffer overflow in C?.

v7d8dpo4
  • 1,399
  • 8
  • 9