Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
Suppose I have a char* word = "abaradasaddragfavvdavgasbga00rarcrawabr0ac0ra0ra0vra0"
and I want to remove all the '0' chars from the word, in place, without using extra-memory or memmove. How could I do it?
So the output would be: "abaradasaddragfavvdavgasbgararcrawabracraravra"
** What I have tried **:
void removeZeros( char* word) {
int size = strlen( word );
int i;
for( i = 0; i < size; i++ ){
if( word[i] == '0' ){
word[ i ] = word[ i + 1 ];
i++;
}
}
}
* Rules **:
should be done in place
should not call any built-in function like memmove or remove
should not use extra-memory
should not assign it to another variable
#include <algorithm>
#include <iostream>
using namespace std;
int main()
{
char word[] = "abaradasaddragfavvdavgasbga00rarcrawabr0ac0ra0ra0vra0";
int size = strlen( word ) + 1;
std::remove(word, (sizeof(char) * size) + word, '0');
std::cout << word;
}
// this assumes your variable word is really a cstr and is NULL terminated
// also, it assumes that it's not in read only memory space like your small
// example shows but is actually in-place writeable
char* write_position = word;
char* scan_position = word;
for( ; *scan_position != '\0'; scan_position++ ) {
if( *scan_position == '0' ) continue;
*(write_position++) = *scan_position;
}
*write_position = '\0';
Iterate over the string from start to end. For each 0 you find, increment an integer called offset, say. For every non-0 character, move it down by the current value of offset. Make sure to put a null byte on the end.
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
The task is to create a function which will return the last word of a string. For example in a string
Danas je divan dan!
the function should return dan, without the !.
Another example is
Danas je divan dan
where the function should again return dan, but it has to ignore all of the spaces after that word.
Here is what I have come up with so far :
#include <stdio.h>
char *PosljednjaRijec(char *s) {
char *p = s;
while (*p != '\0')
p++;
while (*p != ' ')
p--;
p++;
return p;
}
int main() {
printf("Posljednja rijec: %s", PosljednjaRijec("Danas je divan dan!\n"));
printf("Posljednja rijec: %s", PosljednjaRijec(" Danas je divan dan "));
return 0;
}
My question is how to return the last word, without anything behind her such as whitespaces or other signs? I'm having problems with ignoring everything after the last word.
If you are allowed to modify the array, just set a '\0' terminator after the last word found. If not, you need to allocate memory and return a copy of the last word, to be later freed with free().
Note that in your main function, you pass string constants to the PosljednjaRijec function, so it should not modify the array pointed to by its argument, declaring it as const char *s would make this more explicit. Hence only the second option is safe and since you do not free the return value, you have memory leaks.
Note also that your current implementation has undefined behavior if the argument array does not contain any spaces.
Here is a solution:
#include <stdio.h>
#include <string.h>
char *PosljednjaRijec(const char *s) {
int i, j = strlen(s);
while (j > 0 && s[j - 1] == ' ')
j--;
for (i = j; i > 0 && s[i - 1] != ' '; i--)
continue;
char *p = malloc(j - i + 1);
if (p) {
memcpy(p, s + i, j - i);
p[j - i] = '\0';
}
return p;
}
EDIT: with your extra requirements, you could modify the function to return a pointer to the first character of the last word, along with an int stating the number of characters in the last word. You probably want to skip all white space characters, which is easy to do with isspace() defined in <ctype.h>:
#include <ctype.h>
#include <stdio.h>
#include <string.h>
char *PosljednjaRijec(const char *s, int *plen) {
int i, j = strlen(s);
while (j > 0 && isspace((unsigned char)s[j - 1]))
j--;
for (i = j; i > 0 && !isspace((unsigned char)s[i - 1]); i--)
continue;
*plen = j - i;
return (char *)(s + i);
}
int main() {
int len;
char *p;
p = PosljednjaRijec("Danas je divan dan!\n", &len);
printf("Posljednja rijec: '%.*s'\n", len, p);
p = PosljednjaRijec(" Danas je divan dan ", &len);
printf("Posljednja rijec: '%.*s'\n", len, p);
return 0;
}
Output:
Posljednja rijec: 'dan!'
Posljednja rijec: 'dan'
Compare the last character x of the last word you found in ASII, if it isn’t from “a” <= x <= “z” and “A” <= x <= “Z” then ‘delete’ it with your way
My question is how to return the last word
Read about character classification functions in <ctype.h>. You might want to use isalpha. However, UTF8 is everywhere, and things might be more complex (consider using libunistring)
You could return a fresh heap-allocated string (either use calloc to allocate it, then fill it appropriately but leave space for the terminating NUL byte; or use asprintf or strndup if you are allowed to use it) and document the convention that it should later be free-d (usually by the caller or later). Or you could return a struct of two members, one being a pointer inside the input string and the other being the number of bytes of that word.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
void lower_string(char s[]) {
int c = 0;
while (s[c] != '\0') {
if (s[c] >= 'A' && s[c] <= 'Z') {
s[c] = s[c] + 32;
}
c++;
}
}
int main(int argc,char *argv[]){
if (argc<2){
printf("Usage :WI_11SI2_12S17048.exe [nama file].txt \n");
exit(0);
}
const char *filename = argv[1];
FILE *fp = fopen(filename,"r");
rewind(fp);
if (fp == NULL){
printf("file doesn't exist.\n");
exit(1);
}
//CHECK WORDS COUNT AND MAX STRING LENGHT
char chr;
int word_count=0;
int chrcount=0;
int max_chrcount = 0;
while ((chr=fgetc(fp)) != EOF ){
if (isspace(chr)){
if (chrcount > 0){
word_count++;
}
max_chrcount = chrcount > max_chrcount ? chrcount : max_chrcount;
chrcount=0;
}else{
chrcount++;
}
}
rewind(fp);
// SORTING ALL STRINGS BEFORE MAKING STRUCT
int t =0;
char buff[max_chrcount];
char buffer[word_count][max_chrcount];
while ((fscanf(fp,"%s",buff)) != EOF ){
lower_string(buff);
strcpy(buffer[t],buff);
t++;
}
for (int z =0 ; z < t ; z++){
if (buffer[z] != NULL ){
for (int b = z+1 ; b <= t ; b++){
if(strcmp(buffer[z],buffer[b]) == 0){
strcpy(buffer[b],"0");
}
}
}
}
for(int z = 0 ; z <= t ;z++){
if(buffer[z] != "0"){
printf("%s\n",buffer[z]);
}
}
return 0;
}
TEXT in FILE :
SEPATU DALAM KOTAK
kotak sepatu
dalam kotak sepatu yang lain ada sandal dan kaos kaki
sandal **berwarna biru** milik ibu
ayah dan ibu suka memakai sepatu
but when print, I get berwarnabiru and biru instead of berwarna and biru
i am sorry , anyone can help me ?
last , anyone can help me to store that in struct and make the output like this :
sepatu: 4
kotak: 3
dalam: 2
dan: 2
ibu: 2
sandal: 2
ada: 1
ayah: 1
berwarna: 1
biru: 1
kaki: 1
kaos: 1
lain: 1
memakai: 1
milik: 1
suka: 1
yang: 1
I can spot following problems:
The first rewind(fp); is useless and wrong. Useless because after opening the file, the file pointer it is already at the beginning, and wrong because if the file could not be opened for some reason, fp is NULL and rewind(NULL) is undefined behaviour, most likely you'll get a crash.
The computing of word_count is wrong, because you simply count the number of spaces, which is one less than the number of words, unless the file ends with at least one space: Example: "One two three": two spaces here but three words.
fgetc returns an int, not a char, therefore you should have int chr;.
if(buffer[z] != "0") is always false. For comparing strings you need strcmp.
And finally: max_chrcount contains the maximum word length which is computed correctly, but you need one byte more to store the NUL terminator, therefore you need this:
char buff[max_chrcount + 1];
char buffer[word_count][max_chrcount + 1];
However there are most likely more problems.
nd I'm not quite sure what the purpose of strcpy(buffer[b],"0") is. Did you mean buffer[b][0] = 0 ?
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
Im trying to find the end of a word for example school and at the end of a word put a s on to it.
Here is what I have so far:
for (int i = 0; i < 10; i++) {
plural[i] = orig[i];
if (plural[i] == NULL) {
plural[i] = 's';
plural[i + 1] = '\0';
}
}
Your code may function of the string in orig is less than 10 characters long and NULL is defined as 0.
But note that NULL is used to represent the null pointer, not the null byte at the end of a string. NULL can be defined this way:
#define NULL ((void*)0)
In this case, your code would generate a warning upon compilation.
It is considered good style to write '\0' for the null byte at the end of a string. The null character constant has the same value, 0 with type int, but is more explicit for the purpose of representing the null byte.
You should test if orig[i] is non null instead of iterating to 10:
char orig[] = "world";
char plural[10];
int i;
for (i = 0; orig[i] != '\0'; i++) {
plural[i] = orig[i];
}
plural[i] = 's';
plural[i + 1] = '\0';
You can determine the position of null-terminator ('\0') by the following:
int len;
for(len = 0; cstr[len]; ++len);
This is a possible minimal implementation of strlen which is stands for to determine the length of a char array. In example:
#include <stdio.h>
int main() {
char cstr[10] = "Test";
size_t len;
for(len = 0; cstr[len]; ++len);
if(sizeof(cstr) > len + 1) {
cstr[len++] = 's';
cstr[len] = '\0';
}
printf("%s\n", cstr);
}
Note: As David C. Rankin mentioned in comments, you have to protect the array bounds. Knowing that this is an array, you can read its size with the sizeof operator.
The most important part of this exercise is to insure you learn to protect your array bounds. If you declare an array of char [10], then the longest string it can hold is 9-chars + the nul-byte. If you plan to add a character to the end (e.g. 's'), then that means the original string can be no longer than 8-chars.
If you declare plural as:
char plural[10] = ""; /* note the initialization to all `0` */
then the maximum number of characters that can be held in plural in order to use plural as a string is sizeof plural - 1 chars (*preserving space for the nul-byte). So you can set a max for the length of your string with:
char plural[10] = ""; /* note the initialization to all `0` */
int max = sizeof plural - 1;
Then after you find your original string length, you can validate that there is sufficient room for the nul-byte, e.g.
if (len >= max) { /* validate room for 's' available */
fprintf (stderr, "error: adding 's' will exceed array size.\n");
return 1;
}
Putting all the pieces together in a short example, you could do something similar to the following:
#include <stdio.h>
int main (int argc, char **argv) {
char plural[10] = "", *def = "school";
int len = 0,
max = sizeof plural - 1;
if (argc == 1) { /* if no argument given, copy def to plural */
char *p = def;
for (int i = 0; *p && i < max; i++, len++)
plural[i] = *p++;
}
else /* otherwise copy argv[1] to plural */
len = snprintf (plural, max, "%s", argv[1]);
if (len >= max) { /* validate room for 's' available */
fprintf (stderr, "error: adding 's' will exceed array size.\n");
return 1;
}
plural[len] = 's'; /* add 's' - (nul-terminated via initialization) */
printf ("original : %s\nappended : %s\n", argc > 1 ? argv[1] : def, plural);
return 0;
}
Example Use/Output
$ ./bin/plural
original : school
appended : schools
$ ./bin/plural 12345678
original : 12345678
appended : 12345678s
$ ./bin/plural 123456789
error: adding 's' will exceed array size.
note: if you are more comfortable with array indexes than with pointer arithmetic, you can use the following equivalent statement for the length finding and copy:
if (argc == 1) /* if no argument given, copy def to plural */
for (int i = 0; def[i] && i < max; i++, len++)
plural[i] = def[i];
else /* otherwise copy argv[1] to plural */
len = snprintf (plural, max, "%s", argv[1]);
Look things over. There are many, many different ways to approach this. A normal addition would be to include string.h and use strlen and strcpy or memcpy instead of a loop to find your length or copy characters to plural (note: for long strings memcpy will be more efficient, but for 10 char -- it makes no difference) Let me know if you have any questions.
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 7 years ago.
Improve this question
I want to compare strings, each character with all other, whether they be in the same position or has an equal number in another position.
I don’t know how to use the compare of strings correctly, I tried with a for and while loop with a count but I don’t know.
My problem is this. For example.
My password is 1234.
My test is 1234.
In this case i have 4 deaths. Because the numbers are in the same position. But in this case.
My password is 1234.
My test is 1243.
I have 2 deaths because 1 and 2 are in correct position but 4 and 3 are in other position but they are in the other string.
In this case i have 2 deaths and 2 injuries.
Sorry for my english not very good . Thanks for help..
strcmp will not give you the number of characters matching in the given strings. Try the below code, It will give number of matching characters in the input strings.
#include <string.h>
int GetMatchingChars (const char *s1, const char *s2)
{
int len1;
int len2;
int count = 0;
int minLen = 0;
char *shortPtr = NULL;
char *longPtr = NULL;
/* First check if the string are equal, return either len, no need to go further */
if (strcmp (s1, s2) == 0) {
return strlen(s1); /* or s2 */
}
len1 = strlen (s1);
len2 = strlen (s2);
minLen = (len1 <= len2)? len1:len2;
shortPtr = (len1 <= len2)? s1:s2;
longPtr = (shortPtr == s1)? s2:s1;
/* Loop through the shorter string */
while (*shortPtr != '\0') {
if (*shortPtr == *longPtr) {
count++;
}
shortPtr++;
longPtr++;
}
return count;
}
int main()
{
char *s1 = "saac";
char *s2 = "sbab";
printf ("Matching len = %d\n", GetMatchingChars (s1,s2));
}
if you have two strings like below:
char *str1="Hai", *str2="Hai";
Use strcmp(str1,str2) for comparing two strings in C
It will return
0 => if str1==str2
>0 => if str1 > str2, which is lexicographically compared
<0 => if str1 < str2
Adding a point to above answer.
no need to use for loop while comparing, as strncmp takes the strings as input.
strncmp delcaration is
int strncmp(const char *s1, const char *s2, size_t n);
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
Here is a part of code which describes a function to reverse characters of a string
(Based on exercise 1-19 of Brian W. Kernighnan Programming in C)...
( I have googled various text reverse function, but all of them us pointers or using strrev(), but I don't have an idea what a pointer is.... nor do I want to use strrev(), hence I made a reverse string function as the author wanted it to be........ )
The function:
void reverse(char s[])
{
int i , n ;
char j ;
i = 0 ;
while(s[i] != '0') //And not EOF
{
++n;
}
for(i = 0; i < n; ++i)
{
j = s[i] ;
s[i] = s[n - 1] ;
s[n - 1] = j ;
}
}
However I think overwritting arrays is bad , and the whole function seems awry.
P.S : It would be great if you did check and help me with the whole code here, since it would be offtopic if I did post it here, The code's main return 0; however it still doesn't work....
[EDIT]
Ok I am seriously sorry for troubling you for a typo... I can't delete this question since it has answers with upvotes however I'm sorry....
The correct function would be :
void reverse(char s[])
{
int i, l;
char temp;
for (l = 0; s[l] != '\0'; ++l);
l--;
for (i = 0; i < l; ++i) {
temp = s[i];
s[i] = s[l-1];
s[l-1] = temp;
--l;
}
}
Full Code is here :
Code
Code Working is here :
UPDATE:
I created a correct and working solution for the word 'hello':
#include <stdio.h>
int main(void)
{
char s[] = "hello";
char temp;
// do the swapping here..
temp = s[0];
s[0] = s[4] ;
s[4] = temp ;
temp = s[1] ;
s[1] = s[3] ;
s[3] = temp ;
temp = s[2] ;
s[2] = s[2] ;
s[2] = temp ;
printf("%c, %s ", temp, s);
}
I don't know where you got this piece of code, but it's actually quite broken:
n is never initialized. This is undefined behavior.
The while loop won't terminate at all because it compares a char with a value that is not in the range of a char.
The while loop can't do anything sensible since its body can't change the loop condition.
The for loop exchanges all characters with one single array element, which effectively rotates the string right by one char. But the program will never reach this point anyway.
The loop
while(s[i] != EOF)
{
++n;
}
seems wrong.
String end is checked via 0, not via EOF.
You never change i, so that you always check s[0].