LinuxQuestions.org
Did you know LQ has a Linux Hardware Compatibility List?
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
Search this Thread
Old 11-04-2010, 09:44 PM   #1
trist007
Member
 
Registered: May 2008
Distribution: Slackware
Posts: 972

Rep: Reputation: 56
How do I point a char pointer to a part of another char array?


Programming in C.
I have two char arrays.

char buf1[1024];
char buf2[1024];

Aren't buf1 and buf2 also pointers?

I read in 1024 bytes into buf1 which contain about 300 bytes of characters with newlines. The data is basically a few English sentences. I'm trying to scan buf1 for newlines and then stop at the 1st newline and copy the rest of the data from that 1st newline into buf2.

So I run a for loop to look for that new line.
Code:
for(i=0; i<1024;i++)  {
    if((strcmp(&buf1[i], "\n")) == 0)  {
           buf2 = buf1[i+1];       // trying to set buf2 to point to the data after the first newline in buf1
          }
    }
In the for loop do I have to use &buf1[i] or will buf[i] work as well?

However I'm getting the error 'incompatible types of assignment' for the line
buf2 = buf1[i];

Could somebody explain this process better. On the above statement buf2 is a pointer and buf1[i] is a string? a char?

Please be as detailed as possible. I really want to understand this.

Last edited by trist007; 11-04-2010 at 09:51 PM.
 
Old 11-04-2010, 10:57 PM   #2
Dark_Helmet
Senior Member
 
Registered: Jan 2003
Posts: 2,786

Rep: Reputation: 368Reputation: 368Reputation: 368Reputation: 368
Ok, I think you're getting some things jumbled.

You declare buf1 and buf2 as:
Code:
char buf1[1024];
char buf2[1024];
Therefore, you are declaring buf1 and buf2 as character arrays.

You need to distinguish the underlying data types from what the data type represents. I say that because I think you're getting confused by thinking that character arrays, character pointers, and strings are all synonymous--they aren't.

A string is an interpretation of underlying data. The compiler looks at a starting memory address, and "displays" each byte as a character until it reaches a byte with a value of 0 (the end-of-string marker).

A character pointer is a variable that stores a memory address, and indicates that the memory it's addressing contains characters. But the pointer's value (the address itself) can be modified.

A character array is a variable fixed at one memory address, with enough space available to store a fixed number of characters. For lack of a better analogy, think of it as a constant character pointer--the address cannot be modified.

Now, you can use both a character pointer and a character array whenever you need to supply a string to your code. And I think that might be part of what's tripping you up. A character array, with no subscript, is a pointer to the first element in the array. When you apply a subscript to an array, you're left with the character value located at that index in the array.

With that out of the way...

Your statement:
Code:
buf2 = buf1[i+1];
is illegal for two reasons. First, as the compiler tells you, they are incompatible types. buf2 is a character array. buf1[i+1] is a character. Therefore, you are trying to assign a character to a character array.

Second, buf2 is a character array, and its location in memory cannot be modified. Therefore, any assignments to buf2 (without an appropriate subscript) will also result in an error.

I assume what you want is for buf2 to contain the same characters as buf1, from a given starting position. You should use the strcpy() or strncpy() functions for that purpose. You will need to use the address-of operator (&) that you touched on in your post to make this work correctly. For example:
Code:
strcpy( buf2, &buf1[i+1] )
If you want the "simplicity" of your original statement to work (buf2 = &buf[i+1]), then you will need to use a character pointer for buf2. Though, doing so might cause lots of grief if you are not familiar with all the pitfalls of working with pointers.

Last edited by Dark_Helmet; 11-04-2010 at 11:01 PM.
 
Old 11-04-2010, 11:02 PM   #3
kbp
Senior Member
 
Registered: Aug 2009
Posts: 3,758

Rep: Reputation: 643Reputation: 643Reputation: 643Reputation: 643Reputation: 643Reputation: 643
I seem to keep pointing people to this, but it really is easy to follow:

http://www.highercomputingforeveryone.com/

Carl takes you through the basics in very small steps,

Regarding your immediate problem, you really shouldn't copy a buffer one character at a time, this will perform badly in terms of compute cycles. Try to come up with a solution that performs a string copy for example, or maybe you could just not allocate buff2 - create and initialise it pointing at [buff1+i]

hth
 
Old 11-05-2010, 01:13 AM   #4
paulsm4
Guru
 
Registered: Mar 2004
Distribution: SusE 8.2
Posts: 5,863
Blog Entries: 1

Rep: Reputation: Disabled
Quote:
do I have to use &buf1[i] or will buf[i] work as well?
&buf1[i] is a pointer. It points to a character. This is correct:
Code:
if((strcmp(&buf1[i], "\n"))..
buf1[i] is a character. This is NOT correct:
Code:
if((strcmp(buf1[i], "\n"))..
<= In fact, it's an almost guaranteed access violation

'Hope that helps
 
Old 11-05-2010, 09:46 AM   #5
trist007
Member
 
Registered: May 2008
Distribution: Slackware
Posts: 972

Original Poster
Rep: Reputation: 56
I don't understand why when you use strcmp()
why wouldn't you use buf1[i] which is a char to compare it with "\n" which is another char?
Why is &buf1[i] which is a memory address where the char in the ith index is stored correct when comparing to another char "\n"?
 
Old 11-05-2010, 11:15 AM   #6
Dark_Helmet
Senior Member
 
Registered: Jan 2003
Posts: 2,786

Rep: Reputation: 368Reputation: 368Reputation: 368Reputation: 368
Quote:
Originally Posted by trist007
I don't understand why when you use strcmp()
why wouldn't you use buf1[i] which is a char to compare it with "\n" which is another char?
Why is &buf1[i] which is a memory address where the char in the ith index is stored correct when comparing to another char "\n"?
Because chars and strings are not the same thing.

First, strcmp() compares strings. By comparing strings, the process necessarily compares individual characters, but strcmp() will continue to compare characters including and until a NULL is encountered.

So, for your first question:
Quote:
why wouldn't you use buf1[i] which is a char to compare it with "\n" which is another char?
1. buf1[i] is a char, correct. That, however, is the problem. strcmp() compares strings. As such, it needs the address of the first character to start comparing--not the value of the first character itself.

2. "\n" is NOT a character. It is a literal string. It is represented in memory as two sequential characters at the following indexes: [0]: \n [1]: NULL. Use of "\n" in code is replaced with the address in memory where the literal string is stored. Please note: "\n" is a literal string -- '\n' is a literal character. The quoting makes a difference.

If you want to compare two characters individually, you would do it like so:
Code:
if( buf1[i] == '\n' )
{
  printf( "Newline found\n" );
}
else
{
  printf( "Not a newline\n" );
}
Quote:
Why is &buf1[i] which is a memory address where the char in the ith index is stored correct when comparing to another char "\n"?
It is syntactically correct. That is, it meets the requirements of strcmp()--two strings as arguments. Whether it is logically correct for your program is another matter.

But your hangup I believe, is again thinking that "\n" is a character. As mentioned above, it is actually a literal string. It represents a sequence of two characters--not one.

Last edited by Dark_Helmet; 11-05-2010 at 11:21 AM.
 
Old 11-05-2010, 12:08 PM   #7
paulsm4
Guru
 
Registered: Mar 2004
Distribution: SusE 8.2
Posts: 5,863
Blog Entries: 1

Rep: Reputation: Disabled
Hi, again:
Quote:
Q: I don't understand why when you use strcmp(). Why wouldn't you use buf1[i] which is a char to compare it with "\n" which is another char?

Why is &buf1[i] which is a memory address where the char in the ith index is stored correct when comparing to another char "\n"?
Code:
  // Compare string "\n" with string "\n":
  char *s = "\n";
  if (strcmp (s, "\n") == 0) ...

  // Since the string is only one byte (plus the null byte delimiter), 
  // then it's equivalent to this:
  if (s[0] == '\n') ...
But that has nothing to do with what I thought was your original question: "can I use strcmp (buf[i]) instead of strcmp (&buf[i])"? No - you can't

PS:
Q: does this make sense?
Quote:
Q: Do I have to use &buf1[i] or will buf[i] work as well?

A: &buf1[i] is a pointer. It points to a character. This is correct:
Code:
if((strcmp(&buf1[i], "\n"))..
buf1[i] is a character. This is NOT correct:
Code:
if((strcmp(buf1[i], "\n"))..

Last edited by paulsm4; 11-05-2010 at 12:09 PM.
 
Old 11-05-2010, 12:43 PM   #8
johnsfine
Guru
 
Registered: Dec 2007
Distribution: Centos
Posts: 5,046

Rep: Reputation: 1100Reputation: 1100Reputation: 1100Reputation: 1100Reputation: 1100Reputation: 1100Reputation: 1100Reputation: 1100Reputation: 1100
Quote:
Originally Posted by trist007 View Post
char buf1[1024];
char buf2[1024];

Aren't buf1 and buf2 also pointers?
Consider this code:
Code:
int count = 5;
...
23 = count; /* error */
count and 23 both can be used as integers. But obviously you can't use 23 as the left side of an assignment.

Similarly,
Code:
char *pnt;
char buf2[1024];
pnt and buf2 both can be used as char pointers, but using buf2 as the left side of an assignment is wrong in the same way using 23 as the left side of an assignment was wrong.

Quote:
Code:
strcmp(&buf1[i], "\n")
...do I have to use &buf1[i] or will buf[i] work as well?
Neither!

buf1[i] is a character, not an address, so passing it as an address to strcmp would seg fault (as many people already explained).
&buf1[i] is the address of a substring that might start with '\n' (which is what you said you want to test) but strcmp would test whether it both starts and ends with '\n', which is not what you want.

So instead of strcmp(&buf1[i], "\n")==0 what you want is buf1[i]=='\n'

Quote:
Originally Posted by trist007 View Post
Why is &buf1[i] which is a memory address where the char in the ith index is stored correct when comparing to another char "\n"?
"\n" is not a char.
"\n" is the address where that char followed by a null is stored.
'\n' is the char.

strcmp compares two sequences of characters, and you must pass it their addresses. To compare individual characters, you just use == as I suggested above.

For the other error...
Quote:
buf2 = buf1[i+1];
Earlier posts have told you the many things wrong with that line of code. But I don't know whether you described what you hoped it would do well enough to get corrected code.

Quote:
stop at the 1st newline and copy the rest of the data
I think that would be
Code:
if ( buf1[i] == '\n' ) {
   strcpy(buf2, buf1+i+1);
   break; }
but it is hard to be sure that is what is intended by your description. It is quite far from what you coded.

Last edited by johnsfine; 11-05-2010 at 12:57 PM.
 
Old 11-06-2010, 07:56 PM   #9
trist007
Member
 
Registered: May 2008
Distribution: Slackware
Posts: 972

Original Poster
Rep: Reputation: 56
Thanks a ton guys, that really cleared it up.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
scanf reading newline into char array while reading 1 char at a time austinium Programming 6 09-26-2010 11:27 PM
[SOLVED] Why is char* a string and not a pointer to a char? el_b Programming 2 09-25-2009 10:33 AM
C string as an array of chars and as a pointer to char Alien_Hominid Programming 16 05-18-2009 08:22 AM
C++ help Dynamic array and "invalid conversion from ‘char’ to ‘char*’" heathf Programming 2 04-25-2009 09:20 PM
How can I assign to a pointer array like char *args[]; ? haydari Programming 3 04-09-2007 11:48 PM


All times are GMT -5. The time now is 02:57 PM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration