-1

My program reads from two files (FirstNames and Lastnames). With the program i have so far, i print a customer ID, and next to it the first name and last name. Now i need to also print the "login ID", which will be the first letter from the first name and all the last name. Here is the program i have so far. I thought it would be easy to make the login id but it's kinda tricky for my level. (if some people have problems compiling it, try declaring the "i" outside the for loops).

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char ** argv)
{
    if ( argc != 2 )
    {
        printf("usage: %s no_of_records\n", argv[0]);
        exit(1);
    }

    int nrecords = atoi(argv[1]);

    typedef struct test
    {
        int num; char *firstName; char *lastName;
    } CU;

    char buf[256];
    char * fname;
    char * lname;
    CU * cup = malloc ( nrecords * sizeof(CU));
    CU * cufirst = cup;

    FILE * fpfirst;
    FILE * fplast;

    if ( (fpfirst = fopen("FirstNames", "r")) == NULL)
    {
        fprintf(stderr, "Error reading file FirstNames");
        abort();
    }
    if ( (fplast = fopen("LastNames", "r")) == NULL)
    {
        fprintf(stderr, "Error reading file LastNames");
        abort();
    }

    for (int i = 0; i < nrecords; )
    {
        cup -> num = ++i;
        fgets(buf, sizeof(buf), fpfirst);   /*  get line    */
        fname = strndup(buf, strlen(buf)-1);    /* omit newline */
        cup -> firstName = (char *)  strdup(fname);

        fgets(buf, sizeof(buf), fplast);
        lname = strndup(buf, strlen(buf)-1);
        cup -> lastName = (char *) strdup(lname);

        cup++;
    }
    cup = cufirst;
    for (int i = 0; i < nrecords; i++)
    {
        printf("%03d\t%s\t\t%s\n", cup -> num, cup -> firstName, cup ->    lastName);
        cup++;
    }
    return 0;
 }
Mr. Branch
  • 442
  • 2
  • 13
paulaxa1
  • 1
  • 1
  • 8
  • Regarding, "(if some people have problems compiling it, try declaring the "i" outside the for loops).", you should only be posting compilable code. – Greg Hilston May 28 '16 at 01:47
  • it is man but when i run it in ubuntu it worked fine, while in lubuntu it had an error and to fix that error you needed to declare the "i" outside the for loop. Linux is weird man, take the chill pill. – paulaxa1 May 28 '16 at 01:53
  • If you write C you should always declare "i" outside the for loops. Declaring the variable inside the for loop is C++ syntax, which might or might not be correctly understood by a C compiler. – Fabel May 28 '16 at 01:59
  • didn't know that, thanks. – paulaxa1 May 28 '16 at 02:01
  • 1
    Declaring the variable inside the for loop is the current standard practice for C programs. The only compilers that won't accept it are obsolete C89 compilers. – user3386109 May 28 '16 at 02:08
  • Using `strndup` to remove the newline is a very bad idea in so many ways. See [this answer](https://stackoverflow.com/a/28462221/3386109) for the correct way to remove the newline. – user3386109 May 28 '16 at 02:15
  • 1
    `i` should be just fine declared where it is. The default C standard was finally changed from `gnu89` to `gnu11` in the 5.x series. If you are using an older compiler than the 5.x series, you can pass the `-std=` flag manually, as in `gcc -std=gnu99`, where `` is one of: `c99`, `gnu99`, `iso9899:1999`. Additionally, GCC 4.6 was the first version to include some support for C11 (`c1x` and `gnu1x`) with GCC 4.7 and GCC 4.9 significantly improving the support. If you have GCC 4.7 or newer, you can use `c11`, `gnu11`, or `iso9899:2011` as the value of ``. –  May 28 '16 at 02:18
  • 1
    @Fabel defining uints/ints inside loops came with the C99 standard (1999), after C++ was already in use. This was in fact taken from c++, but is quite comonly used nowadays in C. As long as you know that you're compiling in C99 or higher there's no problem in defining them inside the loop ( I personally prefer to define outside, but that's a matter of taste). – Mr. Branch May 28 '16 at 02:21
  • Why does the code cast `strdup()` whereas `strndup()` doesn't get casted? Why cast at all? In C it's useless. – alk May 28 '16 at 11:39
  • OT: This `strlen(buf)-1` is route into disaster. Imaging what would happen if `buf` would be `""`. – alk May 28 '16 at 11:40
  • OT^2: Those two calls `?name = strndup(buf, ...` introduce a memory leak. What gets allocated to `?name` never gets freed again. – alk May 28 '16 at 11:42
  • I wonder why you expect us to write your code? – alk May 28 '16 at 11:43
  • did i ever say to write me a code? i posted my code so far that needs improvement. c is weird for new programmers such as myself. Until i get to embrace its simplicity, i will need some help. Thank all of you for your information – paulaxa1 May 28 '16 at 12:55

2 Answers2

0

To print the first letter of the first name followed by the entire last name, use the %c conversion to print the first letter, and the %s conversion to print the last name, like this:

printf( "%c%s", cup->firstName[0], cup->lastName );
user3386109
  • 34,287
  • 7
  • 49
  • 68
0

You just need to add a simple formatting to print the login id.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char **argv) {
    if (argc != 2) {
        printf("usage: %s no_of_records\n", argv[0]);
        exit(1);
    }

    int nrecords = atoi(argv[1]);

    typedef struct test {
        int num;
        char *firstName;
        char *lastName;
    } CU;

    char buf[256];
    char *fname;
    char *lname;
    CU *cup = malloc(nrecords * sizeof(CU));
    CU *cufirst = cup;

    FILE *fpfirst;
    FILE *fplast;

    if ((fpfirst = fopen("FirstNames", "r")) == NULL) {
        fprintf(stderr, "Error reading file FirstNames");
        abort();
    }
    if ((fplast = fopen("LastNames", "r")) == NULL) {
        fprintf(stderr, "Error reading file LastNames");
        abort();
    }

    for (int i = 0; i < nrecords;) {
        cup->num = ++i;
        fgets(buf, sizeof(buf), fpfirst);    /*  get line    */
        fname = strndup(buf, strlen(buf) - 1); /* omit newline */
        cup->firstName = (char *) strdup(fname);

        fgets(buf, sizeof(buf), fplast);
        lname = strndup(buf, strlen(buf) - 1);
        cup->lastName = (char *) strdup(lname);

        cup++;
    }
    cup = cufirst;
    for (int i = 0; i < nrecords; i++) {
        printf("%03d\t%s\t\t%s\t\t%c%s\n", cup->num, cup->firstName, cup->lastName, cup->firstName[0], cup->lastName);
        cup++;
    }
}

Firstnames

Bob
Lars
Carl
Tim

Lastnames

Larsson
Smith
Doe
Andersson

Output

$ ./a.out 2

    001 Bob     Larsson     BLarsson
    002 Lars    Smith       LSmith
Niklas Rosencrantz
  • 25,640
  • 75
  • 229
  • 424
  • 1
    thanks man your answer and user3386109 answer helped me a lot! i cant upvote yet so i leave this thanks you comment here – paulaxa1 May 28 '16 at 12:53
  • this summer i will practice so freakin much.. any book or course recommendations would be appreciated – paulaxa1 May 28 '16 at 20:58