John
John

Reputation: 45

How to copy a string in C until I reach a space

I'm trying to print out the first names and surnames separately by splitting up the string. What I have currently allows me to do it but I have to manually go through every name. I am hoping someone knows how to do this, However I must use pretty common function, like strpcy etc. Is it possible to use a for loop to do it? Thanks so much and any help is appreciated!

// ConsoleApplication24.cpp : Defines the entry point for the console application.

#include "stdafx.h"
#include <string.h>

void main() {
    char names[10][51] = {
        "Pat Townsend", "Michele Kelley", "Yolanda Franklin",
        "Willard Benson", "Ashley Simmons", "Shawn Lawson",
        "John Phelps", "Mildred Wheeler", "Lucy Mendoza",
        "Kelvin Barker" };

    char firstnames[10][51];
    char surnames[10][51];
    int i = 0;

    strncpy_s(firstnames[i], names[i], 4);

    printf("%s", firstnames);

    /* for (i < 1; names[i][i] != ' '; i++) {
        firstnames[i][i] = names[i][1];
        printf("Name = %s", firstnames);
    */     (please ignore this, it's just me trying}
}

Upvotes: 3

Views: 5777

Answers (4)

chqrlie
chqrlie

Reputation: 144949

Your code has several problems:

  • These is no generic way to handle array operations, you must iterate in a loop and perform each operation explicitly.
  • Do not use strncpy_s(): it is a non standard function, documented in Annex K of the Standard, but not necessarily included in actual implementations. Do not however use strncpy as this latter function has error-prone semantics. To make things worse, unlike what the name suggests, these functions are not related as their semantics are substantially different.

There are many ways to split the names into parts: you should be more precise as to whether names must have 2 parts and 2 parts only, whether they can contain more than one space... user3121023 suggested a simple method that is flexible on the spaces but fails if the name has more than 2 parts, I tried to improve it and assume first name is a single word.

Here is a simple program that parses the strings into separate parts in a loop and uses 2 more loops to print the parts:

#include <string.h>

int main(void) {
    char names[10][51] = {
        "Pat Townsend", "Michele Kelley", "Yolanda Franklin",
        "Willard Benson", "Ashley Simmons", "Shawn Lawson",
        "John Phelps", "Mildred Wheeler", "Lucy Mendoza",
        "Kelvin Barker" };

    char firstnames[10][51];
    char surnames[10][51];
    int i;

    for (i = 0; i < 10; i++) {
        firstnames[i][0] = lastnames[i][0] = '\0';
        // parse the first word into firstnames[i], skip all spaces
        // and copy the remainder into lastnames[i]
        sscanf(names[i], "%50s %50[^\n]", firstnames[i], lastnames[i]);
    }

    printf("first names:\n");
    for (i = 0; i < 10; i++) {
        printf("    %s\n", firstnames[i]);
    }

    printf("last names:\n");
    for (i = 0; i < 10; i++) {
        printf("    %s\n", lastnames[i]);
    }
    return 0;
}

Upvotes: 0

Rikocar
Rikocar

Reputation: 79

You could use something like:

strncpy_s(firstnames[i], names[i], strcspn(names[i]," "));

strcspn is included in the string.h.

Upvotes: 2

NTDLS
NTDLS

Reputation: 4862

I tried to be as verbose as possible for teaching purposes since you said "we haven't gotten to delimiters yet". This is grossly un-optimized on purpose.

void SplitNames(const char *sFullName, /*out*/char *sFirst, /*out*/char *sLast)
{
    int iWritePosition = 0;
    int iReadPosition = 0;
    int iLength = strlen(sFullName);

    //Parse the first name.
    iWritePosition = 0;
    while (iReadPosition < iLength && sFullName[iReadPosition] != ' ')
    {
        sFirst[iWritePosition++] = sFullName[iReadPosition++];
    }
    sFirst[iWritePosition++] = '\0'; //NULL terminate;


    //Skip spaces.
    while (sFullName[iReadPosition] == ' ')
    {
        iReadPosition++;
    }

    //Parse the last name.
    iWritePosition = 0;
    while (iReadPosition < iLength)
    {
        sLast[iWritePosition++] = sFullName[iReadPosition++];
    }
    sLast[iWritePosition++] = '\0'; //NULL terminate;
}

void main()
{
    char names[10][51] = {
        "Pat Townsend", "Michele Kelley", "Yolanda Franklin",
        "Willard Benson", "Ashley Simmons", "Shawn Lawson",
        "John Phelps", "Mildred Wheeler", "Lucy Mendoza", "Kelvin Barker" };

    for (int iName = 0; iName < 10; iName++)
    {
        char sFirst[255];
        char sLast[255];

        SplitNames(names[iName], sFirst, sLast);

        printf("[%s]= [%s] [%s]\n", names[iName], sFirst, sLast);
    }

    system("pause");
}

Upvotes: 0

Kishore Bandi
Kishore Bandi

Reputation: 5721

In the most primitive way, you could do it like this:

  1. Select Each name in the list
  2. For Each Name selected, keep popping up and saving every character until you either reach a space ' ' or end of string '\0'.

Basic :

int i = 0, j = 0;
char *token = malloc(51);
char separator[2] = " ";

for(i = 0; i < 10; i++)
{
    if(names[i] != NULL) {
        j = 0;
        while(names[i][j] != '\0' && names[i][j] != ' ')
        {
            token[j] = names[i][j++];
        }
        token[j] = '\0';
        printf( "%s\n", token);
    }
}

Alternative: You could use strtok and split the string using the delimiter.

int i = 0;
char *token;
char separator[2] = " ";

for(i = 0; i < 10; i++)
{
    if(names[i] != NULL) {
        token = strtok(names[i], separator);
        printf( " %s\n", token );
    }
}

Upvotes: 0

Related Questions