Coding a string length function using pointer arithmetic - c

I'm in a beginner CS class learning C and we were tasked with coding a function to find string length using only string pointers. I have the following code:
#include <stdio.h>
int strlength(char* str);
int main() {
char *str;
int comp;
printf("Please enter the string: ");
scanf("%s", str);
printf("The length of the string is: %d\n", strlength(str));
return 0;
}
int strlength(char *str) {
int length = 0;
while(*str != '\0') {
length++;
str++;
}
return length;
}
I'm not really sure where I'm getting a segmentation fault. I've tried making a second pointer in the strlength function that equals str and incrementing that, but that also gives me a segmentation fault. Any insight would be appreciated!

char *str;
int comp;
printf("Please enter the string: ");
scanf("%s", str);
You should allocate memory in heap ( with malloc ) for *str before scanf. If you dont want to use malloc change it to char[number] so it can allocate memory in stack instead of heap

Related

Command Flow in C, function call after printf

So I have this super simple C code here taking a user input and prints it out followed by a "T-Plus" while loop. In this case I chose a random name for testing "whoa", but the while loop is not called. My question is, why does the "T-Plus: %d\n" while loop print not be called after the printf() function?:
#include <stdio.h>
char getString();
void tcount(void);
int main(void)
{
tcount();
}
void tcount(void)
{
// class scanf user input
printf("%s", getString());
int i = 1;
do
{
printf("T-Plus: %d\n", i);
i++;
} while( i < 51 );
}
char getString()
{
char name;
printf("Please a string name: \n");
scanf("%s", &name);
return name;
}
Now when I run it, this becomes the output:
$ ./namecount
Please a string name:
whoa
but the T-Plus: string does not get called.
I see two issues here:
1) In function getString() you are trying to read/scan a string in a char, you need memory to store the string and a terminating char, so you can use either of these two ways
Use a char array e.g. char name[50]; or
Use a char pointer and
allocate memory using malloc e.g.
char *p_name = malloc(sizeof(char)*50);
2) You are then trying to return this string which is stored in local variable (which would get destroyed as soon as function ends) so you should use the second approach (use malloc) and return the pointer.
So your code would look like:
#include <stdio.h>
#include <stdlib.h>
char * getString();
void tcount(void);
int main(void)
{
tcount();
}
void tcount(void)
{
// class scanf user input
char *p_name = getString();
printf("%s", p_name);
free(p_name);
int i = 1;
do
{
printf("T-Plus: %d\n", i);
i++;
} while( i < 51 );
}
char *getString()
{
char *p_name = malloc(sizeof(char)*50);
printf("Please a string name: \n");
scanf("%s", p_name);
return p_name;
}
Above answer did not work, Okay so I've edited the code like this, it compiles fine. But raises a segmentation fault though.
#include <stdio.h>
#include <stdlib.h>
char * getString();
void tcount(void);
int main(void)
{
tcount();
}
void tcount(void)
{
// class scanf user input
char *name = getString();
printf("%s", name);
free(name);
int i = 1;
do
{
printf("T-Plus: %d\n", i);
i++;
} while( i < 51 );
}
char * getString()
{
char *p_name[50];
printf("Please a string name: \n");
scanf("%49s", (char *) &p_name);
return *p_name;
}
When the program is run, it asks for your input but still raises a Segmentation fault (core dumped).

Character Pointers with Palindrome Checker in C

This is code I wrote that checks if a string is a palindrome or not. I need to revise this code so that it uses character pointers in it. Could someone give me some suggestions/tips...or show me how to do that? Thanks
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main(){
char string1[20];
int i, length;
int flag = 0;
printf("Enter a string: ");
scanf("%s", string1);
length = strlen(string1);
for(i=0;i < length ;i++){
if(toupper(string1[i]) != toupper(string1[length-i-1])){
flag = 1;
break;
}
}
if (flag)
printf("%s is not a palindrome \n\n", string1);
else
printf("%s is a palindrome \n", string1);
return 0;
}
In your code you use string1[i] to access the current element from the beginning of the string, and string1[length-i-1] to access the current element from the end of the string. You could create two pointers, pb and pe, and then move them toward each other.
To define pointers, use this:
char *pb = &string1[0]; // Or just string1, compiler will convert it to pointer
char *pe = &string1[length-1];
To advance the pointers toward each other, use pb++ and pe--.
To see if the pointers have not crossed each other , check that pb < pe. Currently, your program checks the string twice; there's no need to do that - you can stop as soon as pe becomes less than or equal to the pb.
To access the character pointed to by the current pointer, use
toupper(*pb) != toupper(*pe)
You can combine the check with advancing the pointers, like this:
toupper(*pb++) != toupper(*pe--)
Note: it is not safe to use %s, because when users enter more characters than fits in your string1 buffer overrun results. You should specify the length of the buffer, like this:
scanf("%19s", string1); // Leave one char for null terminator
I'm not sure I completely understand the question, but I think this answers it. You actually are using character pointers. char string1[20] is the same as char *string1. The difference is that you've basically assigned the pointer to a block of memory. You could access the string in this way.
char string[20] = "foo";
printf("%c\n", string[0]); // will print 'f'
printf("%c\n", *string); // will also print 'f'
printf("%c\n", string[1]); // will print the first 'o'
printf("%c\n", *(string + 1)); // will also print the first 'o'
with char * it goes like this
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main()
{
char string1[20];
int i, length;
int flag = 0;
printf("Enter a string: ");
scanf("%s", string1);
length = strlen(string1);
char *start=string1;
char *end=&string1[length-1];
//only check upto half
for(i=0;i <= (length-1)/2 ;i++)
{
if(toupper(*(start+i)) != toupper(*(end-i)))
{
flag = 1;
break;
}
}
if (flag)
printf("%s is not a palindrome \n\n", string1);
else
printf("%s is a palindrome \n", string1);
return 0;
}
cant we just copy the original string to another array, and then use strrev() to reverse the copied string and then finally compare the original string with the reversed string?
Like this
1.get new string
2.copy string to new array
3.reverse the copied string using strrev
4.use strcmp to check if both are same or not?
this seemed easier
(i am a beginner so please correct me if i am wrong)

Passing pointers to string arrays to toupper() in C

I'm trying to pass a pointer array of strings to function toupper() in C.
main() {
char *choice[1];
scanf("%s", choice);
printf("%s", toupper(&choice[0]));
}
I always type in a lowercase word such as "modify" to test it. Different variations of this, such as toupper(*choice[0]) or toupper(*choice) or mixtures of them all, including &, have either thrown an error or returned the same lowercase "modify". Any suggestions?
To start with array of char pointers having one element doesn't make much sense to me since it will only point to one string.Why not declare a char array if you just want a single string?
Prototype of toupper is this:
int toupper( int ch );
It doesn't take an array.
You can try like this :
#include <stdio.h>
#include <ctype.h>
int main()
{
char str[25];
int i = 0;
setbuf(stdout,NULL);
printf ("enter the name \n");
fgets (str,sizeof str-1, stdin);
printf ("the name entered in upper case is :\n");
while (str[i])
{
int c = str[i];
printf ("%c",toupper(c));
i++;
}
return 0;
}
NOTE- Do not use scanf for taking strings try fgets , its better.
Before you call scanf, you need to allocate some space for the characters to be stored in. You only allocate a single pointer and then you don't even set it to point to anything. Similarly, toupper returns the converted character, which is not a string, so passing it to printf through %s is also wrong.
Something like this should serve the purpose.
#include<stdio.h>
#include<ctype.h>
void StrToUpper(char *str)
{
while(*str != '\0')
{
*str = toupper(*str);
str++;
}
}
int main()
{
char *choice[1];
choice[1] = new char[10];
scanf("%s", choice[1]);
StrToUpper(choice[1]);
printf("%s", choice[1]);
return 0;
}
In the program, you have array of pointers.
So:
Allocate memory for your string
call toupper(choice[0][0]);
toupper takes only a character value (between 0 and 255), not a pointer or array.

Print a string using putch with pointers in C

So I'm trying to print an inputted string using putch and a little bit of pointers.
Here is my current code:
#include<stdio.h>
#include<conio.h>
#include<string.h>
void printer(char *c);
char *c;
char ch;
main(){
clrscr();
printf("Enter a string: ");
scanf("%s",&ch);
c = &ch;
printer(c);
getch();
}
void printer(char *c){
int x;
for(x=0;x<strlen(c);x++){
putch(*c);
}
}
The problem is that i can only print the first character of the string, also for some reason strlen always return 3 for strings that are 3 characters and below.
Do I have to use array for this so that I can use putch since it is limited to only 1 character output.
One of the problems is that your printer() function is not printing anything other than the first character. There are two ways of approaching this. Using pointers:
void printer(char const *c){
while ( *c != '\0' ) {
putch(*c);
c++;
}
}
And using pointer arithmetic:
void printer(char const *c) {
int x;
for ( x=0; x < strlen(c); x++ ) {
putch( *(c + x) );
}
}
The biggest problem is that you are attempting to store a string in a single character in memory. That's just asking for problems.
char ch;
scanf("%s",&ch); // NO NO NO NO NO
Instead declare your buffer (to store the string in) as an array big enough for the biggest string you expect:
char ch[512];
scanf("%s", ch);
First off, you pass a pointer to "storage for one character" to scanf. Anything that happens after that is in nsal demons territory.
Second, scanf does not allocate storage for your input, so even if you'd passed c instead of &ch, you would not be any better off.
Third, you really should be declaring your variables inside main rather than using global variables.
Something like this may be closer to what you actually want:
void output (char *c)
{
char *cp;
for (cp = c; *cp; cp++) {
putch(*cp);
}
}
int main (void)
{
char input[80];
printf("Please input a string: ");
scanf("%s\n", input);
output(input);
}
try this code:
#include<stdio.h>
#include<conio.h>
#include<string.h>
void printer(char *c);
char *c;
char buffer[1000];// use as a buffer
void main(){
clrscr();
printf("Enter a string: ");
scanf("%s",buffer);//read the input to the buffer
c=(char*)malloc(strlen(buffer)+1);//alloc memory with len of input + 1 byte to "\0"(end of string)
strcpy(c,buffer);//copy the input from the buffer to the new memory
printer(c);
getch();
free(c);//free the memeory
}
void printer(char *c)
{
int x;
for(x=0;x<strlen(c);x++){//move the index string pointer to next char in the string
putch(c[x]);//print the char to the screen
}
}
1)You cant use char to save a string u need char*!!!
2)You can get input to memory that not allocated!!!! because of that u must read the input to buffer after that alloc string by size of the input inside the buffer!
Your code print only first character because c is always pointing to first character of the array. For printing total string you need to increment character pointer as well
You need to do like this
void printer(char *c){
while(*c != '\0'){
putch(*c);
c++;
}
}
First calculate the length of the string & then use above implementation like this-
void printer(char *c){
int i, length;
length=strlen(c)
for(i=0;i<lenth;i++,c++){
putch(*c);
}
}
It should work I think.
#include<stdio.h>
#include<conio.h>
#include<string.h>
void printer(char *c);
char *c;
char ch;//the ch should be a array
main(){
clrscr();
printf("Enter a string: ");
scanf("%s",&ch);//the ch don't need '&'
c = &ch;//the ch don't need '&'
printer(c);
getch();
}
void printer(char *c){
int x;
for(x=0;x<strlen(c);x++){
putch(*c);
}
}

string rotations

#include <stdio.h>
#include <string.h>
int main()
{
char s[15];
int i,j,n,*str;
printf("Enter a string");
scanf("%s",str);
n=strlen(str);
for(i=0;i<n;i++)
{
str[n]=str[0];
for(j=0;j<n;j++)
{
str[j]=str[j+1];
}
str[n]='\0';
printf("\n %s",str);
}
return 0;
}
this program gives me all possible rotations of string
can anyone explain str[n]=str[0] and str[j]=str[j+1] meaning
instead of taking n=strlen(s) can we use n=strlen(str)
plz explain
This rotates the string. The way it does so is by moving the first character to the last place by doing str[n] = str[0] (str[n] is the string-terminating null character '\0', then shifting the whole string down one (str[j] = str[j+1]), then replacing the null at the end (str[n]='\0').
This code would, if it were using s, cause a buffer overrun if the string is longer than 14 characters. However, there's also a logic error in the code: it should be either initializing str (as a char* not int*) or scanning into s with a length bound. For instance:
scanf("%14s", s);
or
str = (char*)malloc(500);
scanf("%500s", str);
instead of taking n=strlen(s) can we use n=strlen(str)
Actually, since str is an int-pointer that is not initialized anywhere, all uses of str should be replaced by s (it's probably just a typo).
#include <stdio.h>
#include <string.h>
int main()
{
char s[15];
char tmp_var;
int i,j,n,*str;
printf("Enter a string");
scanf("%s",str);
n=strlen(str);
for(i=0;i<n/2;i++)
{
tmp_var = str[i];
str[i] = str[n-i];
str[n-i] = tmp_var;
}
printf("\n Rotated String is %s \n",str);
return 0;
}

Resources