Hey guys I need to write a function that separates a line into five different individual fields. My first question is how do I set the entire line of input from a file to an array. These are my directions.

void dissectCustLine( char *, char *, char *, char *, char *, char * );

This function should separate the entire line of input into five individual fields.

It takes six string arguments:

* a string that contains the entire line of input as read from the custfile.txt file
* a string to pass back the customer name
* a string to pass back the customer street address
* a string to pass back the customer phone number
* a string to pass back the car info
* a string to pass back the car payment

HINT: think about using the strncpy() and strcpy() functions.

You're better of posting this in the C forum, but meh.

The function takes 6 char pointers, pointing to a block of chars terminated by '\0' I presume. You need to separate 1 string into 5 others, guess what the other 5 are for?

char here[7];
char a[2];
char hint[5];

dissectCustLine("Here's a hint", here, a, hint);

cin.getline will give you a line from the file:

#include <iostream>

int main()
{
  char buf[1024];

  if ( std::cin.getline ( buf, sizeof buf ) ) {
    std::cout<< buf <<'\n';
  }
}

Ideally you would use the std::string class, but I'm not sure if you've gotten far enough in your class to be able to use that. With a C-style string, you risk only getting a partial line if, for example, the line is longer than 1023 characters.

I have a few things to say about the design of your function as well, which I assume was created by your teacher.

  • I strongly recommend that you provide parameter names even in the function prototype. This is especially important when you have multiple parameters of the same type that do something different.
  • The first argument is better off being const, that way you can later use the c_str member function of the std::string class without dynamically allocating a temporary buffer or (horrors!) casting away const. const not only helps you catch errors, it also gives readers a better idea of what variables are meant for.
  • The latter five parameters are supposed to hold parts of the string, but how do you know they're big enough? Not only are you unable to recover from a buffer overflow error with this function, you're unable to even recognize that it happened! std::string would fix this cleanly, but with C-style strings, you're stuck with passing another parameter for each one that tells the function how many characters it can safely write.

    Alternatively, classes can be used to clean up a mess of too many function parameters, but once again I can't assume that you've done much class work yet (pun intended).

And you haven't said what the format of the line is. There are two common possibilities: a fixed-length format and a delimited format.

A fixed-length is like this:

name0---addr0---phone0---info0-----pay0---
name1---addr1---phone1---info1-----pay1---
name2---addr2---phone2---info2-----pay2---

(As long as you're only accessing it sequentially, the last field could actually be variable length since the end-of-line character acts as a delimiter.)

You can read this format by reading in the first how-ever-many characters, then the next how-ever-many characters, etc. That could be done with just strncpy and strcpy (which makes me suspect this format). You have to use a little pointer arithmetic too (as opposed to plain old indexing).


On the other hand, a delimited format is like this:

name:addr:phone:carinfo:payment

And is processed by finding the colons, one at a time, extracting the substrings as you go.

> You have to use a little pointer arithmetic too (as
> opposed to plain old indexing).

Just to correct this. You don't have to use pointer arithmetic, but you do have to use the addresses of elements as opposed to just their values. So either of these forms should do:

strncpy (to, line + pos, size);  // pointer arithmetic
strncpy (to, &line[pos], size);  // index and address-of
This article has been dead for over six months. Start a new discussion instead.