reading in strings - problem with "\n"

Discussion of chess software programming and technical issues.

Moderator: Ras

Richard Allbert
Posts: 794
Joined: Wed Jul 19, 2006 9:58 am

reading in strings - problem with "\n"

Post by Richard Allbert »

Hi,

Yet another question!

I've been playing with my own tournament manager program.

When reading in the player names from a .ini file, using fgets()

Code: Select all

while(fgets(readinput , 512 , ini_file))
    {
etc...
I read in a list of player names from the text .ini file - these are then stored in an array player[64].

Each name is read in with a "\n" on the end.

So, when I come to write

"Player 1 vs Player 2"

to a file, it reads

"Player 1
vs Player 2"

How do I remove the "\n" from the end of the 'Player 1\n' ?

I have tried

Code: Select all


char game[256]

strcpy(game,player[0]);
strcat(game," v ");
strcat(game,player[1]);

But that doesn't work.

I've been hunting cplusplus.com for a while now, and no answer. It seems a simple problem?

Thanks!

Richard
mathmoi
Posts: 290
Joined: Mon Mar 13, 2006 5:23 pm
Location: Québec
Full name: Mathieu Pagé

Re: reading in strings - problem with "\n"

Post by mathmoi »

Something like that should do it :

Code: Select all

char sz[50];

/* put somthing in sz */

/* This replace the last character of the string (in your case a '\n') by '\0' that is used to delimit the end of the string */
sz[len(sz) - 1] = '\0';
User avatar
Zach Wegner
Posts: 1922
Joined: Thu Mar 09, 2006 12:51 am
Location: Earth

Re: reading in strings - problem with "\n"

Post by Zach Wegner »

That won't work if the last line ends in EOF. Try:

Code: Select all

char *c;
if (c = strchr(readinput, '\n'))
    *c = '\0';
Anyways, I got rid of fgets a while ago, as I don't like artificial input limits. This came after I implemented UCI, which can potentially have very long input lines. Here's a generic function that will allocate a string big enough. No need to free() it either, as the buffer is free()d next time the function is called.

Code: Select all

char *getln(FILE *stream)
{
    int c;
    int size;
    static char *buffer = NULL;

    if (buffer != NULL)
    {
        free(buffer);
        buffer = NULL;
    }
    size = 0;
    while ((c = fgetc(stream)) != EOF)
    {
        if (buffer == NULL)
            buffer = malloc(1);
        else
            buffer = realloc(buffer, size + 1);
        buffer[size] = c;
        size++;
        if (c == '\0' || c == '\n')
            break;
    }
    return buffer;
}
mathmoi
Posts: 290
Joined: Mon Mar 13, 2006 5:23 pm
Location: Québec
Full name: Mathieu Pagé

Re: reading in strings - problem with "\n"

Post by mathmoi »

I might add that if you are using C++ you should use std::string instead of C-style strings and ifstream instead of stdio.h.
Richard Allbert
Posts: 794
Joined: Wed Jul 19, 2006 9:58 am

Re: reading in strings - problem with "\n"

Post by Richard Allbert »

:D

I know... I just find some c functions easier. :D
Richard Allbert
Posts: 794
Joined: Wed Jul 19, 2006 9:58 am

Re: reading in strings - problem with "\n"

Post by Richard Allbert »

Ok :D ,

Thanks for the reply, appreciated! I'll have a look.

Richard
Richard Allbert
Posts: 794
Joined: Wed Jul 19, 2006 9:58 am

Re: reading in strings - problem with "\n"

Post by Richard Allbert »

Thanks again to you both..... it's worked.

:D
bob
Posts: 20943
Joined: Mon Feb 27, 2006 7:30 pm
Location: Birmingham, AL

Re: reading in strings - problem with "\n"

Post by bob »

Richard Allbert wrote:Hi,

Yet another question!

I've been playing with my own tournament manager program.

When reading in the player names from a .ini file, using fgets()

Code: Select all

while(fgets(readinput , 512 , ini_file))
    {
etc...
I read in a list of player names from the text .ini file - these are then stored in an array player[64].

Each name is read in with a "\n" on the end.

So, when I come to write

"Player 1 vs Player 2"

to a file, it reads

"Player 1
vs Player 2"

How do I remove the "\n" from the end of the 'Player 1\n' ?

I have tried

Code: Select all


char game[256]

strcpy(game,player[0]);
strcat(game," v ");
strcat(game,player[1]);

But that doesn't work.

I've been hunting cplusplus.com for a while now, and no answer. It seems a simple problem?

Thanks!

Richard
Simple solution:

char buffer[];
fgets(buffer, 128, in);
if (strchr(buffer, '\n'))
*strchr(buffer, '\n') = 0;

that will replace the \n on the end of a line with a null, which just shortens the string by one character.
User avatar
WinPooh
Posts: 276
Joined: Fri Mar 17, 2006 8:01 am
Location: Russia
Full name: Vladimir Medvedev

Re: reading in strings - problem with "\n"

Post by WinPooh »

Standard C++ allows more elegant solution:

Code: Select all

std::string s;
getline(std::cin, s);
No fixed limits in size, no '\n' problem.
User avatar
xsadar
Posts: 147
Joined: Wed Jun 06, 2007 10:01 am
Location: United States
Full name: Mike Leany

Re: reading in strings - problem with "\n"

Post by xsadar »

Zach Wegner wrote:That won't work if the last line ends in EOF. Try:

Code: Select all

char *c;
if (c = strchr(readinput, '\n'))
    *c = '\0';
Anyways, I got rid of fgets a while ago, as I don't like artificial input limits. This came after I implemented UCI, which can potentially have very long input lines. Here's a generic function that will allocate a string big enough. No need to free() it either, as the buffer is free()d next time the function is called.

Code: Select all

char *getln(FILE *stream)
{
    int c;
    int size;
    static char *buffer = NULL;

    if (buffer != NULL)
    {
        free(buffer);
        buffer = NULL;
    }
    size = 0;
    while ((c = fgetc(stream)) != EOF)
    {
        if (buffer == NULL)
            buffer = malloc(1);
        else
            buffer = realloc(buffer, size + 1);
        buffer[size] = c;
        size++;
        if (c == '\0' || c == '\n')
            break;
    }
    return buffer;
}
That's a lot of calls to realloc. Why not something more like this?

Code: Select all

char *getln(FILE *stream)
{
    int c;
    int length = 0;
    static int size = 0;  // no need to allocate a new buffer every call
    static char *buffer = NULL;

    if (buffer == NULL)
    {
        // start with a buffer size you think is reasonable for your type of input
        buffer = malloc(32);
        size = 32;
    }
    while ((c = fgetc(stream)) != EOF)
    {
        if (length == size)
        {
            // double the size each time we reallocate
            buffer = realloc(buffer, size * 2);
            size *= 2;
        }
        buffer[length] = c;
        length++;
        if (c == '\0' || c == '\n')
            break;
    }
    return buffer;
}
Keep in mind I didn't test, or even compile it.