What's new

Manipulating strings in C

Slougi

New member
Hi all,
I am on my yearly try to learn how to code in C once again ;) Got further than usually this time =)


Anyway, I was wondering how to modify individual charactes in a string.

Say I have the following code:

Code:
#include <stdio.h>

int main(int argc, char *argv[])
{
	char  abc[20];
	strcpy(abc, "Wahoo!\0");
	printf("%s", abc);
	return 0;
}
This works fine. But this:

Code:
#include <stdio.h>

int main(int argc, char *argv[])
{
	char  abc[20];
	strcpy(abc, "Wahoo!\0");
	printf("%s", abc);
	printf("%s", abc[1]);
	return 0;
}

Gives me a segmentation fault. Why is that? Also, since apparently direct access to the chars does not work, how can I modify individual chars in the string?

If this is completely ridiculous please enlighten me why so :p
 

icepir8

Moderator
Slougi said:
Hi all,
I am on my yearly try to learn how to code in C once again ;) Got further than usually this time =)


Anyway, I was wondering how to modify individual charactes in a string.

Say I have the following code:

Code:
#include <stdio.h>

int main(int argc, char *argv[])
{
	char  abc[20];
	strcpy(abc, "Wahoo!\0");
	printf("%s", abc);
	return 0;
}
This works fine. But this:

Code:
#include <stdio.h>

int main(int argc, char *argv[])
{
	char  abc[20];
	strcpy(abc, "Wahoo!\0");
	printf("%s", abc);
[COLOR=red]	printf("%s", abc[1]);[/COLOR] 
	return 0;
}

Gives me a segmentation fault. Why is that? Also, since apparently direct access to the chars does not work, how can I modify individual chars in the string?

If this is completely ridiculous please enlighten me why so :p

The line in red is wrong in that you are passing a char to it and telling it that you are passing a string.
I belive that this will work.

printf("%c", abc[1]);
 
OP
S

Slougi

New member
Re: Re: Manipulating strings in C

icepir8 said:
The line in red is wrong in that you are passing a char to it and telling it that you are passing a string.
I belive that this will work.

printf("%c", abc[1]);


/me slaps forehead with a large hammer

:whistle:
 

Doomulation

?????????????????????????
Heh. And of course, you can still modify a string:
PHP:
str[5] = 'g';
As an example.
Otherwise it's always better to use char* strings unless using buffers. They can be modified at will.
 
OP
S

Slougi

New member
Doomulation said:
Heh. And of course, you can still modify a string:
PHP:
str[5] = 'g';
As an example.
Otherwise it's always better to use char* strings unless using buffers. They can be modified at will.
I thought that was only in c++?
/me goes read some more
 

Doomulation

?????????????????????????
Nope. Pointers and char are c.
Classes and references are c++.
Ie,
PHP:
class whatever { };
int& whatever;

Pointers are a very useful thing to learn.
The power of c++ lies within classes.
 
Last edited:
OP
S

Slougi

New member
Doomulation said:
Nope. Pointers and char are c.
Classes and references are c++.
Ie,
PHP:
class whatever { };
int& whatever;

Pointers are a very useful thing to learn.
I meant the str[5]= 'g'; bit.
 

Doomulation

?????????????????????????
I know you did :)
But to answer your question, it's possible in c :)
References and classes are mostly the only that isn't possible.
 

Doomulation

?????????????????????????
Heh. You're right. It has nothing to do with pointers.
Char* is pointer. That's what i tried to point out :)

PHP:
char* test = "hello";
char test = new char[20];
test = "hello";

That's pointers.

PHP:
char test = new char[20]; <--- pointer
test[5] = 'g'; <--- not pointer
test = "hello"; <--- pointer
 
OP
S

Slougi

New member
Doomulation said:
Heh. You're right. It has nothing to do with pointers.
Char* is pointer. That's what i tried to point out :)

PHP:
char* test = "hello";
char test = new char[20];
test = "hello";

That's pointers.

PHP:
char test = new char[20]; <--- pointer
test[5] = 'g'; <--- not pointer
test = "hello"; <--- pointer
Doom, I know that :) It is just that for some reason while posting this my brain refused to cooperate with me and notice the %s. Nothing more about this thread :p

Still, thanks for the help :)
 

Cyberman

Moderator
Moderator
well Ok let me give you
ye olde' Cybies tips on using the array operator(tm)

Tip 1
To prevent access violations and exceptions always do a bounds check before accessing a location in any array.

Code:
   char Str[20];
   int Index;

   Str[2]= ' '; // this is BAD programing practice!
   Index = 0;
   while (Index < sizeof(Str)) // good programing practice
   {  Str[Index] = ' ';
      Index++;
   }
Now you are probably wondering a few things why is this any better? Notice the array has 20 characters if you access outside of the array you are writting in a location you have NO BUSINESS to write to and you will get an Illegal Access exception error.

Tip 2
All pointers are arrays except type void.

This means if you assign a pointer allocate memory or typecast one.. be sure the SIZE is correct or an exception WILL ocure.
Code:
#define BUFFSIZE 128
   char *Src;
   int Pos;

   //Src = new char[128]; // this is BAD don't do this 
   Src = new char[BUFFSIZE]; // safer here is why
   Pos = 0;
   while (Pos < BUFFSIZE) // if you just change BUFFSIZE
   {  Src[Pos] = 0;    // you will automatically take care of bounds
   }
   return (void *)Src; // good but you should always retain an 
//original pointer copy instead of using Src could be disasterous 
//later ;)

Type void has no size, hence you can't have an array of type void. You can have an array of void pointers so be very careful.

Cyb
 
Last edited:
OP
S

Slougi

New member
Well, in case you all wonder what I was doing, here is my 1337 1337 filter ;) The commented out printf thingies were for debugging, i had i <= argc... Thanks Jabo for pointing that out :)

Code:
#include < stdio.h >
 
int main(int argc, char *argv[])
{
   int i,j,k;
   char abc[20],regular[8],leet[8];
   regular[0]='a';
   regular[1]='c';
   regular[2]='e';
   regular[3]='i';
   regular[4]='l';
   regular[5]='o';
   regular[6]='s';
   regular[7]='t';
   leet[0]='4';
   leet[1]='(';
   leet[2]='3';
   leet[3]='l';
   leet[4]='1';
   leet[5]='0';
   leet[6]='5';
   leet[7]='7';
   //printf("for starts now!\n");
   for (i=1; i < argc; i++)
     {
        strcpy(abc, argv[i]);
        //printf("for 1\n");
        for (j=0; j < strlen(abc); j++)
          {
             //printf("for 2\n");
             for (k=0; k <= 7; k++)
               {
                  //printf("for 3\n");
                  //printf("i:%d,j:%d,k:%d\n", i, j, k);
                  if (abc[j]==regular[k])
                   {
                      abc[j]=leet[k];
                   }
               }
          }
        printf("%s ", abc);
     }
   printf("\n");
   return 0;
}

Now, if someone thinks this code is bad, please tell me why, and how to fix it :)


EDIT: DAMN HTML!!!! :angry: Please ignore extra spaces
 
OP
S

Slougi

New member
Hmm, ok cyberman's post had some good points in it :) Had clicked reply before the post was there
 

Cyberman

Moderator
Moderator
regular and leet appear to be constants.
you would be better served doing this

Code:
#include < stdio.h >

#define MAX_PARSE 128
int main(int argc, char *argv[])
{
   int i,j,k;
   char abc[20];//,regular[8],leet[8];
   const char regular[] = { "aceilost" }; // these are constants
   const char leet[] = " { "(3l1057" }; // ditto :)
/*   regular[0]='a';
   regular[1]='c';
   regular[2]='e';
   regular[3]='i';
   regular[4]='l';
   regular[5]='o';
   regular[6]='s';
   regular[7]='t';*/
/*   leet[0]='4';
   leet[1]='(';
   leet[2]='3';
   leet[3]='l';
   leet[4]='1';
   leet[5]='0';
   leet[6]='5';
   leet[7]='7';*/
   //printf("for starts now!\n");
   for (i=1; i < argc; i++)
     {
        strcpy(abc, argv[i]);
        //printf("for 1\n");
        for (j=0; j < (MAX_PARSE > strlen(abc))?MAX_PARSE;strlen(abc); j++) // so you don't exceed DOS's built in buffer of 128 chars or whatever
          {
             //printf("for 2\n");
             for (k=0; k <= 7; k++)
               {
                  //printf("for 3\n");
                  //printf("i:%d,j:%d,k:%d\n", i, j, k);
                  if (abc[j]==regular[k])
                   {
                      abc[j]=leet[k];
                   }
               }
          }
        printf("%s ", abc);
     }
   printf("\n");
   return 0;
}

This gives you errors if you acidentally access one of the check arrays and write to them. :)
 
OP
S

Slougi

New member
Thanks for the constant suggestion :) I was looking for a better way to do this.

As to DOS limitations, no worry, I use Linux ;)

Code:
louai@Gondolin louai $ uname -a
Linux Gondolin 2.4.20-gentoo-r2 #1 Sat Mar 22 11:40:02 EET 2003 i686 AMD Duron(tm) 
Processor AuthenticAMD GNU/Linux

Perfect for someone who wants to learn C. It really makes it much easier than Windows/DOS :)
 

Doomulation

?????????????????????????
As I said, pointers is flexible and good.
Instead of filling each array element, use a pointer.

PHP:
char test[20];
test[0] = 'h';
test[1] = 'e';
...
test[19] = '!';
= BAD!

PHP:
char* test;
test = "he...!"; // Good!

Pointers are flexible and with them you can basically do whatever you want and an error won't occour. Remember, though, that you can't use this as buffer.

PHP:
char* buffer;
buffer = ReadAFile(filename_here);

As it's writing data directly into the varaible, you'll get a memory error later. Especially when trying to delete it. However, you can do this:

PHP:
char* test;
test = "hello";
test = "helooooooooooooooooooo";
test = "t";

It'll work. Just remember that pointers need be released with delete.

To further demonstrate the incredible flexinbleness of pointers, you can use them to get arrays with any numbers of elements you don't know.
Just pass for example an array of classes to a function. Use a class pointer of that type and you can do a loop to go through all the elements like a dynamic array. Be careful not to go past the boundary, though.
 
Last edited:
OP
S

Slougi

New member
I don't quite understand why reading a file would not work, but assigning a value to it would?
 

Doomulation

?????????????????????????
Yup.
It's like when you assign a value to it, c++ does something with it. Heh, I don't know quite well actually.
But reading from a stream as a buffer from these functions simply won't work.
Try and you'll see.
 

aprentice

Moderator
Stop confusing slougi with jibberish examples of your "l33t skills" :p First of all, pointers point at the address of the array holding the data. There, was that too hard to explain? :p
 

Top