I'm trying to write a program which gets one or more input lines, and if one line is too long, it gets folded at a maximum number of chars. My approach would be to write the input chars in a first array, of a given length. If Maximum length is reached or '\n' as input, i copy the content in a bigger array which will be the final string to print and get the second line in input. Problem is: it doesn't work and I can't figure out why. Thanks for the help
#include <stdio.h>
#define MAXCOL 10
#define FINAL_LENGTH 300
char line[MAXCOL];
char final_string[FINAL_LENGTH];
extern int fnlstr_pos = 0;
int main()
{
int pos, c;
pos = 0;
while(c=getchar() != EOF)
{
line[pos] = c;
if (pos + 1 >= MAXCOL || c == '\n'){
to_printandi(pos);
pos = 0;
}
++pos;
}
printf("%s", final_string);
}
to_printandi(pos)
int pos;
{
int i;
for(i = 0; i <= pos; ++i){
final_string[fnlstr_pos] = line[i];
++fnlstr_pos;
}
if (final_string[fnlstr_pos] != '\n'){
final_string[++fnlstr_pos] = '\n';
}
++fnlstr_pos;
}
There are several problems in the code. Others have already pointed out the bug in the getchar() line.
More variables and more functions and more code only twist one around in knots. If you take some time to think about what you want to achieve, go slowly, you can get your results with much less effort. Less code full of helpful comments, make for better programs.
EDIT
Looking at code with fresh eyes, I realised that the two lines explicitly setting the 'trailing' byte to '\0' were write 0 overtop of bytes already initialised to 0. Have commented out those two lines as they are superfluous.
#include <stdio.h>
int main () {
char buf[ 1024 ] = { 0 }; // buffer initialised
int ch, cnt = 0, ccnt = 0; // input char and counters
while( ( ch = getchar() ) != EOF ) { // get a character
ccnt++; // count this character
buf[ cnt++ ] = (char)ch; // assign this character
// buf[ cnt ] = '\0'; // string always terminated
if( buf[ cnt-1 ] == '\n' ) // user supplied LF?
ccnt = 0; // reset the counter (for width)
else
if( ccnt == 10 ) { // reached max output width?
buf[ cnt++ ] = '\n'; // inject a LF
// buf[ cnt ] = '\0'; // string always terminated
ccnt = 0; // reset the counter (for width)
}
}
puts( buf ); // output the whole shebang
return 0;
}
0123456789abcdefghijklmnop
qrs
tuv
wxyz
^D // end of input
0123456789
abcdefghij
klmnop
qrs
tuv
wxyz
Like the OP code, this does not test for overrunning the buffer. An easy addition left as an exercise for the reader.
EDIT2:
Then again, why have a buffer to overrun?
#include <stdio.h>
void main( void ) {
for( int ch, n = 0; ( ch = getchar() ) != EOF; /**/ )
if( (n = putchar( ch ) == '\n' ? 0 : n + 1) == 10 )
putchar( '\n' ), n = 0;
}
This question is very broad and it would helpful if you said what the problem is but I can see one issue -- you don't null terminate the final_string variable. add
final_string[fnlstr_pos] = '\0';
before the printf.
Maybe that fixes the problem you are having.
For starters this statement
while(c=getchar() != EOF)
is equivalent to
while( c = ( getchar() != EOF ) )
So c is always equal to1 if EOF is not encountered.
You need to write
while( ( c=getchar() ) != EOF)
And you need to append the input sequence with the terminating zero character '\0' tp form a string.
Another problem is these code snippet with for loop
for(i = 0; i <= pos; ++i){
final_string[fnlstr_pos] = line[i];
++fnlstr_pos;
}
As within the loop the variable fnlstr_pos was increased then this if statement
if (final_string[fnlstr_pos] != '\n'){
final_string[++fnlstr_pos] = '\n';
}
invokes undefined behavior because the variable points to a non-initialized element of the array.
The main problem is here:
while(c=getchar() != EOF)
Given the operator precedence, this will result in the same as:
while(c= (getchar() != EOF))
So c will be 1 (true) inside the loop.
Change this to:
while((c=getchar()) != EOF)
This is the main problem. Just as #Hogan suggested, there are other issues such as not null terminating the strings.
As you declare them global, they will be zeroed so you can get away with that though not in the case the user provides a string with maximum length.
Also it would greatly improve the code if you could use string manipulation functions from <string.h> instead of copying byte by byte.
Related
I'm going to identify the difference between two string. I can't see what I'm missing here. The output from my code is correct by the sample. But when I test run it with other test, it fails. I can't see what the other tests are.
The input:
The first line of input contains an integer 1<= n <= 500, indicating the number of test cases that follow. Each test case is a pair of lines of the same length, 1 to 50 characters. Each string contains only letters (a-z,A-Z) or digits (0-9).
The Output:
For each test case, output the two lines in the order they appear in the input. Output a third line indicating similarities and differences as described above. Finally, output a blank line after each case.
Sample:
int main()
{
int n;
// scan the integer for number of test cases
if(scanf("%d", &n) != 1) {
return 1;
}
//Loop through the test cases
for (int i = 0; i < n; i++)
{
char string1[1024], string2[1024], output[50];
//Scan first and second string
if(scanf("%s", string1) != 1) {
return 1;
}
if(scanf("%s", string2) != 1) {
return 1;
}
//Loop through the strings and compare them
for (int i = 0; string1[i] != '\0' || string2[i] != '\0'; i++)
{
//Convert to lowercase
string1[i] = tolower(string1[i]);
string2[i] = tolower(string2[i]);
//Compare
if (string1[i] == string2[i])
{
output[i] = '.';
} else {
output[i] = '*';
}
}
//Print the strings and the output.
printf("%s\n%s\n%s\n", string1, string2, output);
if(i + 1 < n) {
printf("\n");
}
}
return 0;
}
Maybe the problem is that when you have an input string in upper case ("ABCD") you print it in lowercase in the output ("abcd")?
The output string is never terminated, a '\0' should be added after the loop is over, otherwise printf would read over to the memory filled by previous test cases if their inputs were longer.
There is no great sense to declare the variable n as having the signed integer type int. Declare it at least as having type unsigned int.
unsigned int n;
// scan the integer for number of test cases
if(scanf("%u", &n) != 1) {
return 1;
}
The three character array should be declared as having 51 elements
char string1[51], string2[51], output[51];
The calls of scanf will look like
//Scan first and second string
if(scanf(" %50s", string1) != 1) {
return 1;
}
if(scanf(" %50s", string2) != 1) {
return 1;
}
Also you need to check that the entered strings have the same length as for example
if( strlen( string1) != strlen( string2 ) ) {
return 1;
}
This for loop
for (int i = 0; string1[i] != '\0' || string2[i] != '\0'; i++)
can invoke undefined behavior if the lengths of strings are not equal each other. If you will include the above shown if statement then the for loop can look the following way
size_t i = 0;
for ( ; string1[i] != '\0'; i++ )
These statements change the original strings
//Convert to lowercase
string1[i] = tolower(string1[i]);
string2[i] = tolower(string2[i]);
that you should not do. Just compare corresponding characters like
if (string1[i] == string2[i])
{
output[i] = '.';
} else {
output[i] = '*';
}
If you want to compare characters independent on their cases then write
if ( tolower( ( unsigned char )string1[i] ) == tolower( ( unsigned char )string2[i] ) )
{
output[i] = '.';
} else {
output[i] = '*';
}
After the for loop write
output[i] = '\0';
tp form a string in the array output.
It seems this if statement
if(i + 1 < n) {
printf("\n");
}
is redundant. Just output the new line character '\n'
putchar( '\n' );
after each test case.
Needlessly complicated. And, if the source strings contain any whitespace characters, scanf won't satisfy your needs. Below is both simpler and more robust.
Challenge assures no line more than 50 (or 500???) chars, so use only two small arrays.
Challenge is to also output LF after EVERY test case, so suppressing final one with special code is wrong.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
void readAline( char *p, size_t n ) { // do or die
if( fgets( p, n, stdin ) == NULL )
exit( 1 );
}
int mmain() {
char buf[2][ 50 + 1 + 1 ]; // +2 = up to 50 + LF + '\0' from fgets()
readAline( buf[0], sizeof buf[0] );
int n = atoi( buf[0] );
while( n-- ) {
readAline( buf[0], sizeof buf[0] );
readAline( buf[1], sizeof buf[1] );
// can't be too careful when dealing with input
assert( strlen( buf[0] ) == strlen( buf[ 1 ] ) );
printf( "%s%s", buf[0], buf[1] ); // echo to stdout
// source data defined "up to 50 chars, so no test for '\0'
// recycle buf[0] for output
for( int i = 0; buf[0][i] != '\n'; i++ )
buf[0][i] = buf[0][i] == buf[1][i] ? '.' : '*';
puts( buf[0] ); // uses loaded LF and appended LF
}
return 0;
}
Demonstration
1
the cat sat on the mat
the fat cat in the vat
the cat sat on the mat // here is the echo
the fat cat in the vat
....*...*...*......*.. // here is the analysis
// blank line
#include <stdio.h>
#include <string.h>
int main(){
char c[20], result[50];
int bool = 0, count = 0, i;
while(fgets(c,20,stdin) != NULL){
int stringSize = strlen(c);
if(stringSize == 11){
int ascii = (int)(c[i]);
for(i = 0; i < stringSize; i++){
if(ascii >= 'A' && ascii <= 'Z'){
bool = 1;
}
}
}
}
if(bool == 1){
count++;
strcat(result,c);
}
printf("%d", count);
printf("%s",result);
}
Good morning, I am fairly new to programming, and I've spent quite a while Googling and searching around for this issue already, but I can't seem to wrap my head about it.
Basically I'm trying to filter an fgets so that it reads each string, and if they're capital letters, they're "valid". However, I can't even get the fgets to stop accepting more input.
Edit: The idea is to store in result every String that has 10 capital letters, and for the fgets while loop to break once the user gives no input ('\0')
If you are entering strings from the standard input stream then it is better to rewrite the condition of the while loop the following way
while( fgets(c,20,stdin) != NULL && c[0] != '\n' ){
In this case if the user just pressed the Enter key without entering a string then the loop stops its iterations.
Pay attention to that fgets can append the new line character '\n' to the entered string. You should remove it like
c[ strcspn( c, "\n" ) ] = '\0';
Then you could write
size_t n = strlen( c );
if ( n == 10 )
{
size_t i = 0;
while ( i != n && 'A' <= c[i] && c[i] <= 'Z' ) ++i;
bool = i == 10;
}
Pay attention to that it is a bad idea to use the name bool because such a name is introduced as a macro in the header <stdbool.h>.
Also it seems this if statement
if(bool == 1){
count++;
strcat(result,c);
}
must be within the while loop. And the array result must be initially initialized
char c[20], result[50] = { '\0' };
I'm towards solving the exercise, but just half way, I find it so weird and cannot figure it out,
the next is the code snippet, I know it is steps away from finished, but I think it's worth figuring out how come the result is like this!
#define MAXLINE 1000
int my_getline(char line[], int maxline);
int main(){
int len;
char line[MAXLINE];/* current input line */
int j;
while((len = my_getline(line, MAXLINE)) > 0 ){
for (j = 0 ; j <= len-1 && line[j] != ' ' && line[j] != '\t'; j++){
printf("%c", line[j]);
}
}
return 0;
}
int my_getline(char s[], int limit){
int c,i;
for (i = 0 ; i < limit -1 && (c = getchar()) != EOF && c != '\n'; i++)
s[i] = c;
if (c == '\n'){
s[i] = c;
++i;
}
s[i] = '\0';
return i;
}
It will be compiled successfully with cc: cc code.c. But the following result is subtle!
Iit is working for lines without \t and blanks:
hello
hello
but it does not work for the line in the picture:
I typed hel[blank][blank]lo[blank]\n:
Could anyone help me a bit? many thanks!
The problem is that you are stuck because you try to get a full line and process it. It's better to process (and the problems of K&R are mostly this way all) the input char by char. If you don't print characters as you detect spaces, but save them in a buffer, and print them if there's a nontab character when you read one past the accumulated ones, then everything works fine. This is also true for new lines. You should keep the last (nonblank) character (as blanks are eliminated before a new line) read to see if it is a newline... in that case, the new line you have just read is not printed, and so, sequences of two or more newlines are only printed the first. This is a sample complete program that does this:
#include <stdio.h>
#include <stdlib.h>
#define F(_f) __FILE__":%d:%s: "_f, __LINE__, __func__
int main()
{
char buffer[1000];
int bs = 0;
int last_char = '\n', c;
unsigned long
eliminated_spntabs = 0,
eliminated_nl = 0;
while((c = getchar()) != EOF) {
switch(c) {
case '\t': case ' ':
if (bs >= sizeof buffer) {
/* full buffer, cannot fit more blanks/tabs */
fprintf(stderr,
"we can only hold upto %d blanks/tabs in"
" sequence\n", (int)sizeof buffer);
exit(1);
}
/* add to buffer */
buffer[bs++] = c;
break;
default: /* normal char */
/* print intermediate spaces, if any */
if (bs > 0) {
printf("%.*s", bs, buffer);
bs = 0;
}
/* and the read char */
putchar(c);
/* we only update last_char on nonspaces and
* \n's. */
last_char = c;
break;
case '\n':
/* eliminate the accumulated spaces */
if (bs > 0) {
eliminated_spntabs += bs;
/* this trace to stderr to indicate the number of
* spaces/tabs that have been eliminated.
* Erase it when you are happy with the code. */
fprintf(stderr, "<<%d>>", bs);
bs = 0;
}
if (last_char != '\n') {
putchar('\n');
} else {
eliminated_nl++;
}
last_char = '\n';
break;
} /* switch */
} /* while */
fprintf(stderr,
F("Eliminated tabs: %lu\n"),
eliminated_spntabs);
fprintf(stderr,
F("Eliminated newl: %lu\n"),
eliminated_nl);
return 0;
}
The program prints (on stderr to not interfer the normal output) the number of eliminated tabs/spaces surrounded by << and >>. And also prints at the end the full number of eliminated blank lines and the number of no content lines eliminated. A line full of spaces (only) is considered a blank line, and so it is eliminated. In case you don't want blank lines with spaces (they will be eliminated anyway, as they are at the end) to be eliminated, just assign spaces/tabs seen to the variable last_char.
In addition to the good answer by #LuisColorado, there a several ways you can look at your problem that may simplify things for you. Rather than using multiple conditionals to check for c == ' ' and c == '\t' and c == '\n', include ctype.h and use the isspace() macro to determine if the current character is whitespace. It is a much clearer way to go.
When looking at the return. POSIX getline uses ssize_t as the signed return allowing it to return -1 on error. While the type is a bit of an awkward type, you can do the same with long (or int64_t for a guaranteed exact width).
Where I am a bit unclear on what you are trying to accomplish, you appear to be wanting to read the line of input and ignore whitespace. (while POSIX getline() and fgets() both include the trailing '\n' in the count, it may be more advantageous to read (consume) the '\n' but not include that in the buffer filled by my_getline() -- up to you. So from your example output provided above it looks like you want both "hello" and "hel lo ", to be read and stored as "hello".
If that is the case, then you can simplify your function as:
long my_getline (char *s, size_t limit)
{
int c = 0;
long n = 0;
while ((size_t)n + 1 < limit && (c = getchar()) != EOF && c != '\n') {
if (!isspace (c))
s[n++] = c;
}
s[n] = 0;
return n ? n : c == EOF ? -1 : 0;
}
The return statement is just the combination of two ternary clauses which will return the number of characters read, including 0 if the line was all whitespace, or it will return -1 if EOF is encountered before a character is read. (a ternary simply being a shorthand if ... else ... statement in the form test ? if_true : if_false)
Also note the choice made above for handling the '\n' was to read the '\n' but not include it in the buffer filled. You can change that by simply removing the && c != '\n' from the while() test and including it as a simple if (c == '\n') break; at the very end of the while loop.
Putting together a short example, you would have:
#include <stdio.h>
#include <ctype.h>
#define MAXC 1024
long my_getline (char *s, size_t limit)
{
int c = 0;
long n = 0;
while ((size_t)n + 1 < limit && (c = getchar()) != EOF && c != '\n') {
if (!isspace (c))
s[n++] = c;
}
s[n] = 0;
return n ? n : c == EOF ? -1 : 0;
}
int main (void) {
char str[MAXC];
long nchr = 0;
fputs ("enter line: ", stdout);
if ((nchr = my_getline (str, MAXC)) != -1)
printf ("%s (%ld chars)\n", str, nchr);
else
puts ("EOF before any valid input");
}
Example Use/Output
With your two input examples, "hello" and "hel lo ", you would have:
$ ./bin/my_getline
enter line: hello
hello (5 chars)
Or with included whitespace:
$ ./bin/my_getline
enter line: hel lo
hello (5 chars)
Testing the error condition by pressing Ctrl + d (or Ctrl + z on windows):
$ ./bin/my_getline
enter line: EOF before any valid input
There are many ways to put these pieces together, this is just one possible solution. Look things over and let me know if you have further questions.
This is from page 65 in K&R. Description says that this function returns the string length. Here is the code:
int trim (char s[])
{
int n;
for (n = strlen(s)-1; n >= 0; n--)
if (s[n] != ' ' && s[n] != '\t' && s[n] != '\n')
break;
s[n+1] = '\0';
return n;
}
It looks like it should be returning n+1. Is the null character not considered part of the string?
Example:
char s[4];
s[0] = c, s[1] = a, s[2] = t, s[3] = '\0';
Wouldn't this mean the string size is 3 and that there are 3 usable elements? That function would return 2, which is incorrect.
Also, what is string length defined as then?
You're absolutely correct: the returned "n" in your example == "strlen(s)-1"; not "strlen(s)".
#include <stdio.h>
#include <string.h>
int
trim (char s[])
{
int initial_strlen = strlen(s);
int n;
for (n = initial_strlen-1; n >= 0; n--) {
if (s[n] != ' ' && s[n] != '\t' && s[n] != '\n')
break;
}
s[n+1] = '\0';
printf ("s=%s, initial strlen=%d, current strlen=%d, n=%d\n",
s, initial_strlen, strlen(s), n);
return n+1;
}
int
main (int argc, char *argv[])
{
char buf[80];
strcpy(buf, "cat ");
printf ("trim #1= %d\n", trim (buf));
strcpy(buf, "cat\t\t\t ");
printf ("trim #2= %d\n", trim (buf));
return 0;
}
Sample output:
s=cat, initial strlen=6, current strlen=3, n=2
trim #1= 3
s=cat, initial strlen=9, current strlen=3, n=2
trim #2= 3
You are correct that the given implementation of trim does not return the length of the resulting string.
It is not necessarily incorrect, however.
My copy of K&R (2nd) edition says:
The following function, trim, removes trailing blanks, tabs, and newlines from the end of the string, using a break to exit from a loop when the rightmost non-blank, non-tab, non-newline is found.
/* trim: remove trailing blanks, tabs, newlines */
[... code ...]
strlen returns the length of the string....
Nowhere does it say what trim's expected return value is meant to be. While I agree that its actual return value is unintuitive, it's not necessarily wrong since we aren't told how it's supposed to behave.
Also, you may wish to look at the errata for K&R's The C Programming Language (this example is not listed).
The problem is that it is simply a bad code. it is an example of how code should not be written. As a rule any bad code contains a bug and this example demonstrates this rule.:)
It is a bad code because at least you are even unable to say with confidence what the function has to return.:) And if it does not return strlen( s ) then why it has to return strlen( s ) - 1 especially for empty strings.
I would write the function the following way
size_t trim( char s[] )
{
size_t n = strlen( s );
while ( n != 0 && ( s[n-1] == ' ' || s[n-1] == '\t' || s[n-1] == '\n' ) ) --n;
s[n] = '\0';
return n;
}
Compare my code with the code you showed. In my code it is very clear that if the loop will not be iterated the function will return strlen( s ). That is you even need not to investigate what the loop does. If you remove the loop as for example
size_t trim( char s[] )
{
size_t n = strlen( s );
s[n] = '\0';
return n;
}
the code will be very clear and easy readable. It is an invariant.
As for the loop then it uses the idiom of bidirectional iterators in C++. So again such a code easy to read. And there no any break statement.:)
Take into account that it is important that the function would return sizeof( s ) after removing tralling white spaces. For example it could be used when you would want to concatenate two strings.
I guess there is a bug in the book and the function should have been:
int trim(char s[])
{
int n;
for (n = strlen(s); n > 0; n--) {
if (s[n-1] != ' ' && s[n-1] != '\t' && s[n-1] != '\n') {
break;
}
}
s[n] = '\0';
return n;
}
On the one hand, the terminating zero character is not counted as part of the string length. This is how strlen works, for one example. E.g. string "ABCD" has length 4, which is a natural thing to expect.
On the other hand, the above trim function does indeed return one less than the actual string length. Indeed, it should be returning n + 1.
The string length in your example is indeed 3. That's the correct length. The terminating zero character is not counted as part of the length. If you counted the terminating zero, the length would be 4.
I bought a C book called "The C (ANSI C) PROGRAMMING LANGUAGE" to try and teach myself, well C. Anyhow, the book includes a lot of examples and practices to follow across the chapters, which is nice.
Anyhow, the code below is my answer to the books "count the longest line type of program", the authors are using a for-loop in the function getLine(char s[], int lim). Which allows for a proper display of the string line inside the main() function. However using while won't work - for a reason that is for me unknown, perhaps someone might shed a light on the situation to what my error is.
EDIT: To summarize the above. printf("%s\n", line); won't display anything.
Thankful for any help.
#include <stdio.h>
#define MAXLINE 1024
getLine(char s[], int lim) {
int c, i = 0;
while((c = getchar()) != EOF && c != '\n' && i < lim) {
s[++i] = c;
}
if(c == '\n' && i != 0) {
s[++i] = c;
s[++i] = '\0';
}
return i;
}
main(void) {
int max = 0, len;
char line[MAXLINE], longest[MAXLINE];
while((len = getLine(line,MAXLINE)) > 0) {
if(len > max) {
max = len;
printf("%s\n", line);
}
}
return 0;
}
You have a number of serious bugs. Here's the ones I found and how to fix them.
change your code to postincrement i to avoid leaving the first array member uninitialised, and to avoid double printing the final character:
s[++i] = c;
...
s[++i] = c;
s[++i] = '\0';
to
s[i++] = c;
...
// s[++i] = c; see below
...
s[i++] = '\0';
and fix your EOF bug:
if(c == '\n' && i != 0) {
s[++i] = c;
s[++i] = '\0';
}
to
if(c == '\n')
{
s[i++] = '\n';
}
s[i] = '\0'
Theory
When writing programs that deal with strings, arrays or other vector-type structures it is vitally important that you check the logic of your program. You should do this by hand, and run a few sample cases through it, providing sample inputs to your program and thinking out what happens.
The cases you need to run through it are:
a couple general cases
all the edge cases
In this case, your edge cases are:
first character ever is EOF
first character is 'x', second character ever is EOF
first character is '\n', second character is EOF
first character is 'x', second character is '\n', third character is EOF
a line has equal to lim characters
a line has one less than lim characters
a line has one more than lim characters
Sample edge case
first character is 'x', second character is '\n', third character is EOF
getLine(line[MAXLINE],MAXLINE])
(s := line[MAXLINE] = '!!!!!!!!!!!!!!!!!!!!!!!!...'
c := undef, i := 0
while(...)
c := 'x'
i := 1
s[1] := 'x' => s == '!x!!!!...' <- first bug found
while(...)
c := '\n'
end of while(...)
if (...)
(c== '\n' (T) && i != 0 (T)) = T
i := i + 1 = 2
s[2] = '\n' => s == '!x\n!!!!'
i := i + 1 = 3
s[3] = '\0' => s == '!x\n\0!!!' <- good, it's terminated
return i = 3
(len = i = 3) > 0) = T (the while eval)
if (...)
len (i = 3) > max = F
max = 3 <- does this make sense? is '!x\n' a line 3 chars long? perhaps. why did we keep the '\n' character? this is likely to be another bug.
printf("%s\n", line) <- oh, we are adding ANOTHER \n character? it was definitely a bug.
outputs "!x\n\n\0" <- oh, I expected it to print "x\n". we know why it didn't.
while(...)
getLine(...)
(s := line[MAXLINE] = '!x\n\0!!!!!!!!!!!!!!!!!!!...' ; <- oh, that's fun.
c := undef, i := 0
while(...)
c := EOF
while terminates without executing body
(c == '\n' && i != 0) = F
if body not executed
return i = 0
(len = i = 0 > 0) = F
while terminates
program stops.
So you see this simple process, that can be done in your head or (preferably) on paper, can show you in a matter of minutes whether your program will work or not.
By following through the other edge cases and a couple general cases you will discover the other problems in your program.
It's not clear from your question exactly what problem you're having with getLine (compile error? runtime error?), but there are a couple of bugs in your implementation. Instead of
s[++i] = something;
You should be using the postfix operator:
s[i++] = something;
The difference is that the first version stores 'something' at the index of (i+1), but the second version will store something at the index of i. In C/C++, arrays are indexed from 0, so you need to make sure it stores the character in s[0] on the first pass through your while loop, in s[1] on the second pass through, and so on. With the code you posted, s[0] is never assigned to, which will cause the printf() to print out unintialised data.
The following implementation of getline works for me:
int getLine(char s[], int lim) {
int c;
int i;
i = 0;
while((c = getchar()) != EOF && c != '\n' && i < lim) {
s[i++] = c;
}
if(c == '\n' && i != 0) {
s[i++] = c;
s[i++] = '\0';
}
return i;
}
By doing ++i instead of i++, you are not assigning anything to s[0] in getLine()!
Also, you are unnecesarilly incrementing when assigning '\0' at the end of the loop, which BTW you should always assign, so take it out from the conditional.
Also add return types to the functions (int main and int getLine)
Watch out for the overflow as well - you are assigning to s[i] at the end with a limit of i == lim thus you may be assigning to s[MAXLINE]. This would be a - wait for it - stack overflow, yup.