So i did this program and the purpose is to store a string from the stdin and store in a array of strings. After that, i want to print all the strings stored in the array but in reverse order.
Example:
Input:
abc def hij klm nop
Output:
nop
klm
hij
def
abc
Program:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXLEN 1001
int main(){
char buffer[MAXLEN];
char** strings;
int i = 0;
int j = MAXLEN;
strings = (char**)malloc(sizeof(char*)*MAXLEN);
while(scanf("%s",buffer) == 3)
{
strings[i]=(char*)malloc(sizeof(char)*(strlen(buffer)+1));
strcpy(strings[i],buffer);
i++;
}
printf("%s",strings[0]);
}
Well, i just put the 1st string only to check if it was printing any strings the problem is that if type that in the example it prints (null) instead of the word and what im wondering is why is it pointing to NULL instead of pointing to the string i gave.
Really any help would be appreciated.
The test for successful conversion from stdin is incorrect: scanf() returns the number of conversions, not the number of characters. You should compare the return value to 1. As coded, the loop test fails immediately so strings[0] is not modified, the code has undefined behavior because the array allocated by malloc is uninitialized. This array happens to contain a null pointer at the beginning (because its first bytes are zero by coincidence), and printf prints (null) for null pointers, which is not guaranteed by the C Standard, but a useful indication sometimes.
Furthermore, you should tell scanf() about the maximum length of a word to store into the destination array: scanf("%1000s", buf).
You should also limit the number of words you tore into the array of pointer and test for memory allocation error.
Finally, you need a loop to output the strings in reverse order of input.
Here is a modified version:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXLEN 1001
int main() {
char buffer[MAXLEN];
int i, j;
char **strings = malloc(sizeof(char *) * MAXLEN);
if (strings == NULL)
return 1;
for (i = 0; i < MAXLEN && scanf("%1000s", buffer) == 1; i++) {
strings[i] = strdup(buffer);
if (strings[i] == NULL)
return 1;
}
for (j = i; j-- > 0;) {
printf("%s\n", strings[j]);
free(strings[j]);
}
free(strings);
return 0;
}
Related
I am trying to print each word in a single line of a given sentence. It worked perfectly fine but a '_' appears in end of line. please help me with it and also proper manar to write it.
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
int main() {
char *s,i,check=0;
s = malloc(1024 * sizeof(char));
scanf("%[^\n]", s);
s = realloc(s, strlen(s) + 1);
for(i=0;i<1024;i++ ||check<=2)
{
if(*(s+i)!=' ')
{
printf("%c",*(s+i));
check=0;
}
else
{
printf("\n");
check++;
}
// fflush(stdin);
}
return 0;
}
Output:
dkf fja fjlak d
dkf
fja
fjlak
d SER_
Output2:
-for(i=0;i<20;i++ ||check<=2)-
hello I am suraj Ghimire
hello
I
am
suraj
Ghi
I am not sure your code works as you say..
The type of i is not a char *, so it should be int.
You process the input string without considering the NULL terminating char, which leads to a lot of garbage prints.
You do not release allocated memory.
I suggest this slightly modified version:
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
int main() {
char *s, *p;
/* Allocate a new string and verify the allocation has succeeded. */
s = malloc(1024 * sizeof(char));
if (!s) {
printf("malloc failed\n");
return 1;
}
/* Read from user. */
scanf("%[^\n]", s);
/* Work on a copy of `s` (must simpler and faster than a indexed access). */
p = s;
while (*p) {
if (*p != ' ') {
printf("%c",*p);
}else{
printf("\n");
}
p++;
}
free(s);
return 0;
}
Example output:
$ ./a.out
abc def gh i j kmlm opqrst
abc
def
gh
i
j
kmlm
opqrst
EDIT: As requested by the OP, further details regarding the NULL terminating char.
By convention, strings (array of characters) end with a specific character which we call the NULL terminating char. This character is 0 and marks the end of the string data.
In your example, the buffer which store the string is dynamically allocated in RAM. If you do not check for the NULL terminating character of the string, then you keep processing data as if it is part of the string (but it is not).
Going beyond this character make you access the following memory data (which is part of your program RAM data). Since these data can be anything (ranging from 0 to 255), printing them may lead to "gibberish" because they may not be printable and are definitely not consistent with your string.
In the "best" case the program halts with a "segmentation fault" because you are accessing a memory region you are not allowed to. In the "worst" case you print a lot of things before crashing.
This is typically called a data leak (whether it is RAM or ROM) because it exposes internal data of your program. In the specific case of your example there no sensitive data. But! Imagine you leak passwords or private keys stored in your program .. this can be a severe security issue!
There are a couple issues with your code.
Firstly, you need to check that the for loop does not exceed the bounds of the string.
Your for loop is always set to true because the logical OR operator || has a higher precedence than the comma operator. Because of this the loop will always run unless it gets stopped with break
Lastly your check is never reset to 0 after it reaches a value of 2.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main() {
char *s,i,check=0;
s = malloc(1024 * sizeof(char));
scanf("%[^\n]", s);
s = realloc(s, strlen(s) + 1);
for(i=0; i<strlen(s); i++) {
if(*(s+i) != ' ') {
printf("%c",*(s+i));
check=0;
} else {
printf("\n");
check++;
if (check > 2) break;
}
}
return 0;
}
Output:
Hello, this is a test
Hello,
this
is
a
test
for(i=0;i<1024;i++ ||check<=2)
There are two issues. One is length of string won't always be 1024, so it might be good to determine the length of string before print the string. The other is check<=2, which have to put in the second part of the for loop, so the test will be evaluated. Also it is better to calculate the length of string once. So I store the length of string in len.
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char *s, i, check = 0;
s = malloc(1024 * sizeof(char));
scanf("%[^\n]", s);
s = realloc(s, strlen(s) + 1);
size_t len = strlen(s);
for (i = 0; i < len || check <= 2; i++) {
if (*(s + i) != ' ') {
printf("%c", *(s + i));
check = 0;
} else {
printf("\n");
check++;
}
// fflush(stdin);
}
return 0;
}
I want to have an array of strings and the user to enter a string at a time. The program should either end if the the array is full or when the user skips an input (so the string would be equal to "\n".
Problem is that I have to dynamically allocate memory for each of these strings and I cant find a way to do that efficiently.
Excuse my English on this one but the array should be an array of pointers to char (for example char *pin[MAX])
This is my code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 5
int main()
{
char *pin[MAX];
char s[] = "";
int n = 0;
while(s != "\n"){
printf("Enter a string: ");
gets(s);
pin[n] = malloc(sizeof(char)*strlen(s));
strcpy(pin[n], s);
n++;
if(n = MAX - 1) break;
}
for(int i = 0; i < MAX; i++){
printf("%s ", *pin[i]);
}
return 0;
}
Take input with fgets and store it in a temporary buffer (128 or 256 bytes large etc).
Call strlen on the read string stored in this buffer to see how much to allocate.
Allocate memory with malloc for pointer pin[n] and strcpy the string there.
NOTE:
char *s; ... while(s != is nonsense since s has not been initialized.
s != "\n" is nonsense since that's not how you compare strings in C.
pin[n] == &s; is nonsense because it's just random stuff typed out without the programmer knowing why. Programming by trial & error doesn't work.
In general you need to study arrays and pointers before strings.
I'm still a newbie to C so please forgive me if anything below is wrong. I've searched this up online but nothing really helped.
Right now, I have the following code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void appendStr (char *str, char c)
{
for (;*str;str++); // note the terminating semicolon here.
*str++ = c;
*str++ = 0;
}
int main(){
char string[] = "imtryingmybest";
char result[] = "";
for(int i = 0; i < strlen(string); i++){
if(i >= 0 && i <= 3){
appendStr(result, string[i]);
}
}
printf("%s", result);
}
Basically, I'm trying to add the first 4 characters of the String named string to result with a for loop. My code above did not work. I've already tried to use strcat and strncat and neither of them worked for me either. When I used
strcat(result, string[i]);
It returns an error saying that the memory cannot be read.
I know that in this example it might have been easier if I just did
appendStr(result, string[0]);
appendStr(result, string[1]);
appendStr(result, string[2]);
appendStr(result, string[3]);
But there is a reason behind why I'm using a for loop that couldn't be explained in this example.
All in all, I'd appreciate it if someone could explain to me how to append individual characters to a string in a for loop.
The following code doesnt use your methods but successfully appends the first 4 chars to result
#include <stdio.h>
#include <string.h>
int main()
{
// declare and initialize strings
char str[] = "imtryingmybest";
char result[5]; // the 5th slot is for \0 as all strings are null terminated
// append chars to result
strncat(result, str, 4);
// ^ ^ ^
// | | |- number of chars to be appended
// | | - string to be appended from
// | - string to append to
// print string
printf("result: %s\n", result);
return (0);
}
The result of the above is as wanted:
>> gcc -o test test.c
>> ./test
result: imtr
Let me know if anything is not clear so i can elaborate further
string was ruined by the overflow of result buffer.
appendStr can be executed only once. next time strlen(string) will return 0. because *str++ = 0; has been written to the space of string.
result buffer has only 1 byte space, but you write 2 byte to it in appendStr call.
the second byte will ruin string space.
I suggest debug with gdb.
try to get rid of Magic numbers
#define BUFF_SIZE 10 // define some bytes to allocate in result char array
#define COPY_COUNT 4 // count of chars that will be copied
int main(){
char string[] = "imtryingmybest";
char result[BUFF_SIZE] {}; // allocate some chunk of memory
for(size_t i = 0; i < strlen(string); i++){
if(i < COPY_COUNT){
appendStr(result, string[i]);
}
}
printf("%s", result);
}
I showed the solution code Paul Yang showed the problem
As others have pointed out the code has a simple mistake in the allocation of the destination string.
When declaring an array without specifying its size, the compiler deduces it by its initializer, which in your case means a 0 + the NULL character.
char result[] = ""; // means { '\0' };
However, I think that the bigger issue here is that you're effectively coding a Schlemiel.
C strings have the serious drawback that they don't store their length, making functions that have to reach the end of the string linear in time complexity O(n).
You already know this, as shown by your function appendStr()
This isn't a serious issue until start you appending characters or strings in a loop.
In each iteration of your loop appendStr() reaches the last character of the string, and extends the string, making the next iteration a little slower.
In fact its time complexity is O(n²)
Of course this is not noticeable for small strings or loops with few iterations, but it'll become a problem if the data scales.
To avoid this you have to take into account the growing size of the string.
I modified appendStr() to show that now it starts from the last element of result
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void appendStr (char *str, char c, char *orig)
{
printf("i: %ld\n", str - orig);
for (; *str; str++); // note the terminating semicolon here.
*str++ = c;
*str++ = 0;
}
int main()
{
char string[32] = "imtryingmybest";
char result[32] = "";
for(int i = 0; i < strlen(string); i++) {
if(i >= 0 && i <= 3) {
// I'm passing a pointer to the last element of the string
appendStr(&result[i], string[i], result);
}
}
printf("%s", result);
}
You can run it here https://onlinegdb.com/HkogMxbG_
More on Schlemiel the painter
https://www.joelonsoftware.com/2001/12/11/back-to-basics/
https://codepen.io/JoshuaVB/pen/JzRoyp
I am trying to create a char array based on a single ASCII code. The folowing code does not compile correctly, even though "num" is cast to a char:
//Returns the ASCII counterpart of a number, such as 41 = A, 42 = B, 43 = C, etc.
char numToASCII(int num) {
char[] string = {(char)num, "\0"};
return string;
}
For the task that I am given, it is very important that "string" be a character array/string and not a single char. Any help would be appreciated.
The array must be initialized to constant expressions and your function should return a pointer if you want to return an array.
If you just want to return a char, then use the following code instead:
char numToASCII(int num) {
return (char)num;
}
If you want to return a string which contains the character, then you should use the following code:
#include <stdlib.h>
char *numToASCII(int num) {
/*
* Use malloc to allocate an array in the heap, instead of using a
* local array. The memory space of local array will be freed after
* the invocation of numToASCII.
*/
char *string = malloc(2);
if (!string)
return 0;
string[0] = num;
string[1] = 0;
return string;
}
Use the free() function to free the space allocated by malloc().
Try this..
You want to find the character for the ASCII code,then try this code:
#include<stdio.h>
int main()
{
int num;
printf("\nEnter ASCII Code Number:\t");
scanf("%d", &num);
printf("\nASCII Value of %d: \t%c", num, num);
printf("\n");
return 0;
}
In this code it will get the ASCII code from the user and it will print the character for the ASCII code as default.
Not sure if this helps but pulling text from a file comes back as ascii, I needed a string and got around it by checking the string length, sorry for extra steps as I too am very new.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
FILE *fp;
char firstbuff[yourchoice];
char secondbuff[yourchoice];
char sentence[yourchoice];
int stringlenght;
fp = fopen("test.txt", "r");
//Here add a means of counting the lines in the file as linecount
for(int j = 0; j < linecount; j++)
{
fgets(firstbuff; 1000; fp);
//get string length and use for loop to individually ascii copy as characters into array
stringlength = strlen(firstbuff);
for(int i = 0; i < stringlength; i++)
{
secondbuff[i] = (char)firstbuff[i];
}
//string concat
strcat(sentence, secondbuff);
}
printf("%s\n", sentence);
fclose(fp);
}
How can you code this in C language if the output is like this? I need strings format of the code because our topic is strings.
#include <stdio.h>
#include <stdlib.h>
void main()
{
char my_string[50];
printf("Enter a word:");
scanf("%s", my_string);
printf("Enter a word:");
scanf("%s", my_string);
// Some unknown code here...
// this part is my only problem to solve this.
getch();
}
Output:
Hello -> (user input)
World -> (user input)
HWeolrllod -> (result)
Okay, you need to do some investigating. We don't, as a general rule, do people's homework for them since:
it's cheating.
you'll probably get caught out if you copy verbatim.
it won't help you in the long run at all.
The C library call for user input that you should use is fgets, along the line of:
char buffer[100];
fgets (buffer, sizeof(buffer), stdin);
This will input a string into the character array called buffer.
If you do that with two different buffers, you'll have the strings in memory.
Then you need to create pointers to them and walk through the two strings outputting alternating characters. Pointers are not an easy subject but the following pseudo-code may help:
set p1 to address of first character in string s1
set p1 to address of first character in string s1
while contents of p1 are not end of string marker:
output contents of p1
add 1 to p1 (move to next character)
if contents of p2 are not end of string marker:
output contents of p2
add 1 to p2 (move to next character)
while contents of p2 are not end of string marker:
output contents of p2
add 1 to p2 (move to next character)
Translating that into C will take some work but the algorithm is solid. You just need to be aware that a character pointer can be defined with char *p1;, getting the contents of it is done with *p1 and advancing it is p = p + 1; or p1++;.
Short of writing the code for you (which I'm not going to do), there's probably not much else you need.
void main()
{
char my_string1[50],my_string2[50]; int ptr;
ptr=0;
printf("Enter a word : ");
scanf("%s",my_string1);
printf("enter a word");
scanf("%s",my_string2);
while(my_string1[ptr]!='\0' && my_string2[ptr]!='\0')
{
printf("%c%c",my_string1[ptr],my_string2[ptr]);
ptr++;
}
if(my_string1[ptr]!='\0')
{
while(my_string1[ptr]!='\0')
{ printf("%c",my_string1[ptr]);
ptr++;
}
}
else
{
while(my_string2[ptr]!='\0')
{printf("%c",my_string2[ptr]);
ptr++;
}
}
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void main()
{
char my_string1[50],my_string2[50];
int i,l1=1,l2=0;
printf("Enter a word:");
scanf("%s", my_string1);
printf("Enter a word:");
scanf("%s", my_string2);
l1=strlen(my_string1); /* Length of 1st string */
l2=strlen(my_string2); /* Length of 2nd string */
if(l1==l2)
{
for(i=0;i<l1;i++)
{
printf("%c%c",my_string1[i],my_string2[i]);
}
}
else
{
printf("Length of the entered strings do not match");
}
}
This is your required code.
You can see that output needs to be a String containing all chars of User String1 and User String2 one by one...
You can do this like...
//add #include<String.h>
int l1=strlen(s1);
int l2=strlen(s2);
if(l1!=l2)
{
printf("length do not match");
return 0;
}
char ansstr[l1+l2];
int i,j=0,k=0;
for(i=0;i<l1+l2;i=i+2)
{
ansstr[i]=s1[j];
ansstr[i+1]=s2[k];
j++;
k++;``
}
//ansstr is your answer
Ok, here's your code. Come on guys, if he asked here it means he can't solve this.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
char str1[] = "abcdefghijklmopq";
char str2[] = "jklm";
int len1 = strlen(str1);
int len2 = strlen(str2);
int c1 = 0, c2 = 0;
int max = (len1 > len2) ? len1 : len2 ;
char *result = malloc(len1 + len2);
for(c1 = 0; c1 <= max; c1++) {
if(c1 < len1)
result[c2++] = str1[c1];
if(c1 < len2)
result[c2++] = str2[c1];
}
result[c2] = 0;
printf("\n%s\n", result);
return 0;
}
Basically the loop picks up a character from str1 and appends it to result. Then it picks a character, which stands in the same position as the first from str2 and appends it to result, just as before. I increment c2 by 2 every time because I'm adding 2 chars to result. I check if c1 is bigger that the length of the strings because I want to copy only the characters in the string without the terminating \0. If you know that your strings have the same length you can omit these ifs.