How to properly empty a string (array of chars) in C? [duplicate] - c

This question already has answers here:
Proper way to empty a C-String
(7 answers)
Closed 3 years ago.
I used a string called "comando" as the input. I copy the first word of "comando" into "comandoParz" and I use "comandoParz" as the parameter to call a specific function.
The first call works fine, but the second one gives the same output as the first one.
Maybe it's because I need to empty the array "comando" and "comandParz" but I tried a few solutions and none of them seemed to work.
I'll include the full code below.
(Sorry if I added too much code; I'm still trying to figure out the best way to post here.)
I tried adding strcpy(comandoParz, "") and strcpy(comando, "") (they are not active in the code I posted below) and the first input works but the other ones don't give any output.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void addrel() {
printf("\nAGGIUNGI RELAZIONE:\n\n");
}
void delrel() {
printf("\nELIMINA RELAZIONE:\n\n");
}
void addent() {
printf("\nAGGIUNGI UTENTE:\n\n");
}
void delent() {
printf("\nELIMINA UTENTE:\n\n");
}
int main() {
int i = 0;
char comando[100];
char comandoParz[10];
START:
/*strcpy(comando, "");
strcpy(comandoParz, "");*/
printf("Input: ");
fgets(comando, sizeof(comando), stdin);
while(comando[i] != '\0') {
comandoParz[i] = comando[i];
i++;
}
i++;
if(strcmp(comandoParz, "delent\n") == 0) {
delent();
} else {
if(strcmp(comandoParz, "addent\n") == 0) {
addent();
} else {
if(strcmp(comandoParz, "addrel\n") == 0) {
addrel();
} else {
if(strcmp(comandoParz, "delrel\n") == 0) {
delrel();
}
}
}
}
goto START;
}
For example, the first input may be "addrel" and the output will be "AGGIUNGI RELAZIONE:". The second input may be "delent" and the answer should be "ELIMINA UTENTE:" but it will be "AGGIUNGI RELAZIONE" as the first call.

The code needs to re-initialise i to 0 within the START-loop.
A C-string need to be terminated with a 0.
The copy-loop needs to take care to not overwrite the destination array when copying.
Taking all of the above into account this
while(comando[i] != '\0') {
comandoParz[i] = comando[i];
i++;
}
i++;
could look like:
i = 0;
while (comando[i] != '\0'
&& i < (sizeof comandoParz -1)) /* one less for the '\0'-terminator */
{
comandoParz[i] = comando[i];
i++;
}
comandoParz[i] = '\0'; /* place the '\0'-terminator */
To answer you question
how to properly empy a string
You could memset it with '\0':
memset(comandoParz, '\0', sizeof comandoParz);
Although for all methods expecting a C-string putting a '\0' into the array element where you want the string to end would do.
So to "empty" it just do, placing a '\0' in its 1st element:
comandoParz[0] = '\0';

Related

C - C file won't count correctly, it is 1 short [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
I'm brand new to C and struggling with some syntax. My goal is to read through a text document in my directory and return a count it's length.
#include <stdio.h>
#include <stdio.h>
#include <ctype.h>
int counter (FILE* inPtr) { //Pointer to the file its reading from
char ln[len]; \\length of file
int counter = 0; \\initializing file
while(fgets(ln,len,inPtr) != NULL{
char* r;
for (r = ln; *r != '0';) {
while (isspace(*run)) {
r++;
}
if(*r == '\0') {
break;
}
else {
counter++;
}
r++;
}
return(counter);
}
}
Basically, I'm just trying to go past the spaces between words, break when we go over the length (when it runs to null), and count as we go. And then it keeps running until it points to no a space or null. I think I have the right idea by syntax is off...any advice?
There are many syntax issues in your code:
you include <stdio.h> twice
single line comments are started with //, not \\
the null pointer is defined as NULL, not null
there is a missing ) in while(fgets(ln,len,inPtr) != null {
there is a spurious ; in if(*r == '\0'); {
you probably mean to test *r != '\0' instead of *r != '0' if the for loop.
you should move the return counter; outside the body of the while loop.
Here is a modified, reformated and simplified version:
#include <stdio.h>
#include <ctype.h>
int counter(FILE *inPtr) { // Pointer to the file its reading from
char ln[256]; // line buffer
int counter = 0; // number of non white space characters in file
while (fgets(ln, sizeof(ln), inPtr) != NULL) {
for (char *r = ln; *r != '\0'; r++) {
if (!isspace((unsigned char)*r)) {
counter++;
}
}
}
return counter;
}
Here is an even simpler version reading one byte at a time:
#include <stdio.h>
#include <ctype.h>
// return number of non white space characters in file from current position
int counter(FILE *inPtr) { // Pointer to the file its reading from
int c, counter = 0;
while ((c = getc(inPtr)) != EOF) {
counter += !isspace(c);
}
return counter;
}
If your purpose is to count words instead of bytes, you should modify it to skip whitespace, test if at end of line, increment the word count and skip all non whitespace bytes inside the while loop body:
// return the number of space separated words in the file
int counter(FILE *inPtr) { // Pointer to the file its reading from
char ln[256]; // line buffer
int counter = 0; // number of space separated words in the file
while (fgets(ln, sizeof(ln), inPtr) != NULL) {
for (char *r = ln;;) {
// skip white space before the word
while (isspace((unsigned char)*r) {
r++;
}
if (*r == '\0') // end of the line
break;
counter++; // count the word
// skip the word
while (*r != '\0' && !isspace((unsigned char)*r) {
r++;
}
}
}
return counter;
}

C - How to replace a \n with a null in a text file

I'm brand new to C and struggling. Basically, what I need to do is, go through an array, find the \n, and replace it with null. I'm sort of struggling with how I'd go about this. I sort of get it.
In pseudo, based on other minimal coding experience, I want to iterate over an array (for loop), if the string is = "\n" then replace it with null, and if the string is already null, it means we're at the end, so you have to break.
void replaceNwO (char* txtPtr) {
char *txtPtr = strstr(filepath,"\n");
for (i = 0; i < TEXT_LEN; i++) {
if(txtPtr != null) {
strncpy(txtPtr,"\0",1);
char* = strstr(filepath,"\n");
}
else {
i++;
}
}
Can somebody help me see what I'm doing wrong? Pointers are confusing me. My logic is to iterate over a given file path name (a text file in my dir), iterate until we are at the text length capacity, and then replace those new line chars with a null line char. Otherwise, keep iterating.
I'm really trying...but more experienced eyes may help
Loop through the string until you get to a null character. At each step, check if the current character is newline, in which case you replace it with the null character.
To replace a character, just assign through the pointer.
void replaceNwO (char* txtPtr) {
for (; *textPtr != '\0'; textPtr++) {
if (*textPtr == '\n') {
*textPtr = '\0'; // replace newline with null
}
}
}
I would make this function a bit more universal:
It is good to return the pointer to the string. It allows you to use it directly in the function calls or assignments
Function can be much more univeral not only for this replacement in your program.
Add some simple parameter chack (at leat NULL pointer will not be dereferenced.
char *replace(char *haystack, char needle, char replace, int breakAfterFirst)
{
char *wrk = haystack;
if(haystack)
{
while(*wrk)
{
if(*wrk == needle)
{
*wrk == replace;
if(breakAfterFirst) break;
}
wrk++;
}
}
return haystack;
}
void replaceNwO (char* txtPtr) {
char *txtPtr = strstr(filepath,"\n");
while(*txtPtr != '\0')
{
if(*txtPtr == '\n')
{
*txtPtr = '\0';
break;
}
else
{
txtPtr++;
}
}

C programming, meaningless figures on console [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I wrote code to reverse a sentence that the user inputs, but when I run this code and write a sentence, this code prints meaningless figures instead of reverse version of my sentence. I need helping locating the error
#include <stdio.h>
#include <string.h>
void reverser(char*);
int readmassage(char[], int);
int main()
{
char mysentence[30];
readmassage(mysentence, 30);
reverser(mysentence);
printf("%s", mysentence);
system("pause");
return 0;
}
void reverser(char *massage)
{
char temp,*p;
p = massage + strlen(massage)-1;
while (p > massage) {
temp = *massage;
*massage = *p;
*p-- = temp;
}
}
int readmassage(char massage[], int lenght)
{
int ch, i = 0;
while (ch = getchar() != '\n') {
if (lenght > i)
massage[i++] = ch;
}
massage[i] = '\0';
return i;
}
Your problem is here:
temp = *massage;
*massage = *p;
*p-- = temp;
massage always points to the first character in your string here. So you keep overwriting the first character, and then writing the new first character to the last character on the next go round. The effect is that you essentially rotate the string by one character instead of reversing it. If you change *massage = *p; to *massage++ = *p; (or create a new incrementing pointer variable to correspond to p which you initialize to massage), it'll probably work.
What I'm saying is that your "start of the string" pointer needs to be... massaged. ba dum chshhhh
EDIT: And you also need to change this, in readmessage:
while (ch = getchar() != '\n')
to:
while ((ch = getchar()) != '\n')
Otherwise, rather than the input character, you're actually setting ch to 0 or 1, depending on whether getchar() is returning '\n' or not. This is because due to the order of operations, != actually gets executed before =, and != gives you 1 if the expression is true and 0 if it is false. This 0 or 1 then gets stored in ch by the = operator.
You could also just replace all of readmessage with fgets, as it's included in the standard library and meant for exactly this sort of thing (unless reimplementing it was part of your assignment, of course).
EDIT:
Adding explanation. There are some issues with your code, few major, few not that serious
Don't use void main(). It's not the best thing to use.
Indenting your code will make it easier to read
Let's look at the readmassage function.
You are assigning the result of getchar() to an int. That's not right. it should be a char
here's a version of your code with minor fixes
#include <stdio.h>
#include <string.h>
void reverser(char*);
int readmassage(char[], int);
void main()
{
char mysentence[30];
readmassage(mysentence, 30);
printf("Input: %s", mysentence);
reverser(mysentence);
printf("Output: %s", mysentence);
system("pause");
return 0;
}
void reverser(char*massage)
{
char temp,*p;
p = massage + strlen(massage)-1;
while (p > massage) {
temp = *massage;
*massage = *p;
*p-- = temp;
}}
int readmassage(char massage[], int lenght)
{
char ch;
int i = 0;
while (ch != '\n')
{
ch = getchar();
printf("Here\n");
if (lenght > i)
{
massage[i++] = ch;
printf("%c\n", massage[i]);
}
}
massage[i] = '\0';
return i;
}
When you try this you will find that the input string gets read fine, just be sure to not to hi Enter after every character and instead type the full string out as \n is a valid character that can be in the stream and will terminate the loop the next iteration.
This is why you should use a char array reading function like fgets.
Once you get here you can see that the reverser is just following a slightly flawed reversing logic.
grammatical errors aside, fixing this you can get
here you go
#include <stdio.h>
#include <string.h>
void reverser(char* message)
{
int start, end;
start = 0;
end = strlen(message) - 1;
char temp;
while (start < end) {
temp = message[start];
message[start] = message[end];
message[end] = temp;
start++;
end--;
}
}
void readmessage(char message[], int length)
{
fgets(message, length , stdin);
}
int main()
{
char mysentence[30];
readmessage(mysentence, 30);
printf("Read the string\n");
reverser(mysentence);
printf("%s\n", mysentence);
return 0;
}
please debugg to find out the reason sometimes.. It will help you..
The problem is when you call readmassage(mysentence, 30) inside the function you have the string input.
When the flow comes back to the method the value is no more there as you had passed mysentence by value..
And you send null to reverse()..
Pass by reference will work..

Returning a string [char pointer] from a function [duplicate]

This question already has answers here:
Return char[]/string from a function [duplicate]
(5 answers)
Closed 8 years ago.
I am writing a program that returns a string from stdin, but i am getting warning that it returns an adress of local wariable. How can i return the string?
thanks in advance
#include <stdio.h>
char* readLine()
{
int i;
char input[1024];
for(i=0;i<1024;i++)
{
input[i]=fgetc(stdin);
if(input[i]=='\n')
{
break;
}
}
return input;
}
int main()
{
printf("%s",readLine());
return 0;
}
This should work for you:
You can pass input from main as reference:
#include <stdio.h>
char * readLine(char * input, int length) {
int i;
for(i = 0; i < length; i++) {
input[i] = fgetc(stdin);
input[length] = '\0';
if(input[i] == '\n')
break;
}
return input;
}
int main() {
int length = 1024;
char input[length+1];
printf("%s", readLine(input, length));
return 0;
}
Try to do something like that instead:
#include <stdio.h>
char* readLine()
{
int i;
char *input;
if ((input = malloc(sizeof(char) * 1024)) == NULL)
return (NULL);
for(i=0;i<1024;i++)
{
input[i]=fgetc(stdin);
if(input[i]=='\n')
{
input[i] = '\0';
break;
}
}
return input;
}
int main()
{
char *str;
if (str = readLine()) != NULL) {
printf("%s\n", str);
free(str);
}
return 0;
}
}
There is nothing wrong here - that is just a WARNING because usually it is a common mistake of new programmers. I used to run into problems with this usage all the time.
The first thing... this "string" is not null-terminated. You'll want to put at the end of that function something like *(input + i) = '\0'; and make either the array size 1025 or the condition i < 1023 (so that the null character isn't assigned beyond the end of the buffer), because at the moment using this array in a function that expects null termination will cause it to possibly continue past the end of the array, resulting in a memory access violation. Alternately, you could use memset(input,0,1024);, just still make sure that the condition is something like i < 1023 so that the standard input you receive doesn't end up writing all the way to the last null character in the array.
The other problem is that this memory is local, as in it "belongs" to this function. And for the usage you have here, it is probably just fine to use the same memory... if you plan to call the function, do something with the result, and then call the function again, do something with the result... But if you want to keep what's given to you by it, you'll have to either (1) copy the string to another buffer that isn't going to be written to again when the function is called in the future, or (2) make the function allocate a new buffer each time it runs, and then be sure to delete that memory when you're done with it. For example, instead of char input [1024]; (which by the way would have the same pointer for the life of the program, so it's not really necessary to return it each time) you could write char* input = malloc(1024); and later, when the caller is done with the string, you should free(input);. (Of course, the name might not be input in this case since you would probably not want to free the memory in the function whose purpose is to allocate it.)
I will edit this later with code showing changes.

Remove characters from a string in C [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Remove characters from a string in C
I'm creating a small todo application in C and I'd like to remove * then a space from a string I'm looping over each line then checking if the lineNumber is the one passed in to the function then I'd wondering how to remove the characters from that line, Heres the code where I loop over the lines
while (fgets(line, sizeof line, oldTodoFile)) {
len = strlen(line);
if (len && (line[len - 1] != '\n')) {} else {
lineNumber++;
if (lineNumber == todoNumber) {
// remove *[space]
} else {
fprintf(todoFile);
}
}
Sounds like you're asking how to remove a leading '* ' from the beginning of a string. You have two options:
You can either just move each character two spaces back, something like:
if(startsWithStarSpace) {
int i;
for(i = 2; i < len; ++i)
str[i-2] = str[i];
str[i] = '\0';
}
Or if your string is dynamically allocated, you can just move the pointer forward by two characters (making sure to save your old pointer to free() later).
a simple way to do this (note i know this is not the best way, i'm sure there is lots of standard functions for this) would be:
if(lineNumber == todoNumber) {
char buff[len];
char* bptr = buff;
char* lptr = line;
for(;lptr!=NULL;) {
if(*lptr!='*')
*bptr++ = *lptr++
else{
lptr++;lptr++; /*skip over * and space */
}
}
strcpy(line,buff); /* replace line with updated version */
}
Like I said, not the best solution but its one way to do it.

Resources