I am doing this programming problem where I have reverse string of about 30 characters for 10 test cases.
My code is this:-
#include <stdio.h>
#include <string.h>
int main () {
int t;
scanf("%d",&t);
while (t--) {
char str[30];
scanf("%s",&str);
char revStr[30];
int len = strlen(str);
int i = 0;
int j = len-1;
while (i < len) {
revStr[i] = str[j];
i++; j--;
}
printf("%s\n",revStr);
}
return 0;
}
The output gets garbled up if the input string is larger than previous string.
For example,
if last-string had 6 characters, like rocket\0 and new-string, which is fun\0 has 3 characters, the output is funket\0.
char str[30];
scanf("%s",&str);
^ don't pass address of array
Just this would work -
scanf("%29s",str);
Try this:
int t;
scanf("%d", &t);
while (t--)
{
char str[30] = { 0 };
scanf("%s", &str);
char revStr[30] = { 0 };
int len = strlen(str);
int i = 0;
int j = len - 1;
while (i < len) {
revStr[i] = str[j];
i++; j--;
}
printf("%s\n", revStr);
}
You need to make two changes
Firstly change scanf("%s",&str); to
scanf("%s",str);
Secondly, after the while loop, you are not making the last element rev string \0. Add this line before the printf statement.
revStr[i] = '\0';
This should solve your problem.
Related
Given some number in a form of string, I want to extract every k-th number from it. Then I go through the remaining string and extract every k-th number again. The thing I get as a result should be the number formed by these extracted ones(in a proper order). Example: 123456789, k = 3 --> 369485271
My algorithm is as follows: While the lenght of the string allows extracting every k-th number, I go through the string and store every k-th element in another string. Then I delete the extracted elements from the original string by tracking the proper index of an element and proceed forvard while the lenght of my str is sufficient.
I can't figure out what's the problem with my code. And maybe my approach isn't that good and there are some better/simpler ways of diong this?
#include <stdio.h>
#include <string.h>
void remove(char *str, unsigned int index) {
char *src;
for (src = str+index; *src != '\0'; *src = *(src+1),++src) ;
*src = '\0';
}
int main() {
char number[100];
char result[100];
int k;
printf("Enter a string: ");
scanf("%s",number);
printf("Enter a key: ");
scanf("%d",&k);
while (strlen(number)>k-1) {
for (int i = 0, p = 0; number[i] != '\0'; i++) {
if (i % k == (k-1)) {
result[p] = number[i];
p++;
}
}
for (int j = 0; number[j] != '\0'; j++){
if (j % k == (k-1)) {
remove(number, j);
j+=1; /*since the index was shifted due to removing an element*/
}
}
}
puts(result);
return 0;
}
You some issues:
You start writing your output from scratch again in each iteration of your while loop.
You do not handle the last digits
You do not treat the input as a cyclic input.
You do not terminate your output string.
remove is already a name of standard library function.
A shorter version could be this (untested):
#include <stdio.h>
#include <string.h>
void remove_digit(char *str, unsigned int index) {
char *src;
for (src = str+index; *src != '\0'; *src = *(src+1),++src)
;
}
int main() {
char number[100];
char result[100];
int k;
printf("Enter a string: ");
scanf("%s",number);
printf("Enter a key: ");
scanf("%d",&k);
int p = 0;
int i = 0;
int skip = k-1; // We remove 1 digit and skip k-1 digits
while (number[0] != 0) {
i = (i + skip) % strlen(number);
result[p] = number[i];
p++;
remove_digit(number, i);
}
number[p] = 0;
puts(result);
return 0;
}
The following code seems to be what you want:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void remove_(char *str, unsigned int index) {
char *src;
for (src = str+index; *src != '\0'; *src = *(src+1),++src) ;
*src = '\0';
}
int main(int argc, const char * argv[]) {
char number[100];
char result[100];
int tmp[100];
int k;
printf("Enter a string: ");
scanf("%s",number);
printf("Enter a key: ");
scanf("%d",&k);
int p = 0;
for (int tp = 0; strlen(number) > k-1; tp = 0) {
for (int i = 0; number[i] != '\0'; i++)
if (i % k == (k-1))result[p++] = number[i];
for (int j = 0; number[j] != '\0'; j++)
if (j % k == (k-1)) tmp[tp++] = j;
for (; tp; --tp) remove_(number, tmp[tp-1]);
}
// The newly added code
for (int index; strlen(number); ) {
index = (k-1) % strlen(number);
result[p++] = number[index];
remove_(number, index);
}
puts(result);
return 0;
}
The most important thing is that every while loop, you need to remove the elements in number at once. While ensuring the integrity of your original code, I made some changes. Unfortunately, the main idea of the original code is wrong.
It should circulate from the tail (including the rest) to the head after one round. But I found that the function of the code you provided is that after each round, the next round starts from the 0th element of the head.
By the way, your algorithm is similar to the Josephus problem
I am writing a code for the function maxCharToFront() that accepts a character string str as parameter, finds the largest character from the string (based on ASCII value), and moves it to the beginning of the string.
Main function:
#include <stdio.h>
#include <string.h>
void maxCharToFront(char *str);
int main()
{
char str[80], *p;
printf("Enter a string: \n");
fgets(str, 80, stdin);
if (p=strchr(str,'\n')) *p = '\0';
printf("maxCharToFront(): ");
maxCharToFront(str);
puts(str);
return 0;
}
This is the function using for loop:
void maxCharToFront(char *str)
{
int i, maxcharint=0, maxindex=0;
char maxchar;
for (i=0; str[i] != '\0'; i++){
if ( (int)str[i]> maxcharint){
maxcharint = (int)str[i];
maxindex = i;
}
i++;
}
for (i = maxindex-1; i>-1; i--){
str[i+1]= str[i];
}
maxchar = maxcharint;
str[0]= maxchar;
}
when I enter ab as input, it gives back ab as output for for loop.
This is the function using while loop:
void maxCharToFront(char *str)
{
int i=0, maxindex=0, maxcharint=0;
char maxchar;
while (str[i]!='\0'){
if ((int)str[i]>maxcharint){
maxindex = i;
maxcharint = (int)str[i];
}
i++;
}
for(i=maxindex-1; i>-1; i--){
str[i+1]=str[i];
}
maxchar = maxcharint;
str[0] = maxchar;
}
When I enter ab as input, it successfully gives back ba as output for while loop.
However, I don't see a difference in my while and for loop since both transverses all the characters in the input string starting from str[0]. Why is there an output difference? Thank you.
in for loop you increment i twice, once in for loop and once more later on i++
void maxCharToFront(char *str)
{
int i, maxcharint=0, maxindex=0;
char maxchar;
for (i=0; str[i] != '\0'; i++/*increment here*/){
if ( (int)str[i]> maxcharint){
maxcharint = (int)str[i];
maxindex = i;
}
i++; // increment twice
}
for (i = maxindex-1; i>-1; i--){
str[i+1]= str[i];
}
maxchar = maxcharint;
str[0]= maxchar;
}
So I have an assignment where I should delete a character if it has duplicates in a string. Right now it does that but also prints out trash values at the end. Im not sure why it does that, so any help would be nice.
Also im not sure how I should print out the length of the new string.
This is my main.c file:
#include <stdio.h>
#include <string.h>
#include "functions.h"
int main() {
char string[256];
int length;
printf("Enter char array size of string(counting with backslash 0): \n");
/*
Example: The word aabc will get a size of 5.
a = 0
a = 1
b = 2
c = 3
/0 = 4
Total 5 slots to allocate */
scanf("%d", &length);
printf("Enter string you wish to remove duplicates from: \n");
for (int i = 0; i < length; i++)
{
scanf("%c", &string[i]);
}
deleteDuplicates(string, length);
//String output after removing duplicates. Prints out trash values!
for (int i = 0; i < length; i++) {
printf("%c", string[i]);
}
//Length of new string. The length is also wrong!
printf("\tLength: %d\n", length);
printf("\n\n");
getchar();
return 0;
}
The output from the printf("%c", string[i]); prints out trash values at the end of the string which is not correct.
The deleteDuplicates function looks like this in the functions.c file:
void deleteDuplicates(char string[], int length)
{
for (int i = 0; i < length; i++)
{
for (int j = i + 1; j < length;)
{
if (string[j] == string[i])
{
for (int k = j; k < length; k++)
{
string[k] = string[k + 1];
}
length--;
}
else
{
j++;
}
}
}
}
There is a more efficent and secure way to do the exercise:
#include <stdio.h>
#include <string.h>
void deleteDuplicates(char string[], int *length)
{
int p = 1; //current
int f = 0; //flag found
for (int i = 1; i < *length; i++)
{
f = 0;
for (int j = 0; j < i; j++)
{
if (string[j] == string[i])
{
f = 1;
break;
}
}
if (!f)
string[p++] = string[i];
}
string[p] = '\0';
*length = p;
}
int main() {
char aux[100] = "asdñkzzcvjhasdkljjh";
int l = strlen(aux);
deleteDuplicates(aux, &l);
printf("result: %s -> %d", aux, l);
}
You can see the results here:
http://codepad.org/wECjIonL
Or even a more refined way can be found here:
http://codepad.org/BXksElIG
Functions in C are pass by value by default, not pass by reference. So your deleteDuplicates function is not modifying the length in your main function. If you modify your function to pass by reference, your length will be modified.
Here's an example using your code.
The function call would be:
deleteDuplicates(string, &length);
The function would be:
void deleteDuplicates(char string[], int *length)
{
for (int i = 0; i < *length; i++)
{
for (int j = i + 1; j < *length;)
{
if (string[j] == string[i])
{
for (int k = j; k < *length; k++)
{
string[k] = string[k + 1];
}
*length--;
}
else
{
j++;
}
}
}
}
You can achieve an O(n) solution by hashing the characters in an array.
However, the other answers posted will help you solve your current problem in your code. I decided to show you a more efficient way to do this.
You can create a hash array like this:
int hashing[256] = {0};
Which sets all the values to be 0 in the array. Then you can check if the slot has a 0, which means that the character has not been visited. Everytime 0 is found, add the character to the string, and mark that slot as 1. This guarantees that no duplicate characters can be added, as they are only added if a 0 is found.
This is a common algorithm that is used everywhere, and it will help make your code more efficient.
Also it is better to use fgets for reading input from user, instead of scanf().
Here is some modified code I wrote a while ago which shows this idea of hashing:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define NUMCHAR 256
char *remove_dups(char *string);
int main(void) {
char string[NUMCHAR], temp;
char *result;
size_t len, i;
int ch;
printf("Enter char array size of string(counting with backslash 0): \n");
if (scanf("%zu", &len) != 1) {
printf("invalid length entered\n");
exit(EXIT_FAILURE);
}
ch = getchar();
while (ch != '\n' && ch != EOF);
if (len >= NUMCHAR) {
printf("Length specified is longer than buffer size of %d\n", NUMCHAR);
exit(EXIT_FAILURE);
}
printf("Enter string you wish to remove duplicates from: \n");
for (i = 0; i < len; i++) {
if (scanf("%c", &temp) != 1) {
printf("invalid character entered\n");
exit(EXIT_FAILURE);
}
if (isspace(temp)) {
break;
}
string[i] = temp;
}
string[i] = '\0';
printf("Original string: %s Length: %zu\n", string, strlen(string));
result = remove_dups(string);
printf("Duplicates removed: %s Length: %zu\n", result, strlen(result));
return 0;
}
char *remove_dups(char *str) {
int hash[NUMCHAR] = {0};
size_t count = 0, i;
char temp;
for (i = 0; str[i]; i++) {
temp = str[i];
if (hash[(unsigned char)temp] == 0) {
hash[(unsigned char)temp] = 1;
str[count++] = str[i];
}
}
str[count] = '\0';
return str;
}
Example input:
Enter char array size of string(counting with backslash 0):
20
Enter string you wish to remove duplicates from:
hellotherefriend
Output:
Original string: hellotherefriend Length: 16
Duplicates removed: helotrfind Length: 10
I'm parsing a text file:
Hello, this is a text file.
and creating by turning the file into a char[]. Now I want to take the array, iterate through it, and create an array of arrays that splits the file into words:
string[0] = Hello
string[1] = this
string[2] = is
This is my code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "TextReader.h"
#include <ctype.h>
void printWord(char *string) {
int i;
for (i = 0; i < strlen(string); i ++)
printf("%c", string[i]);
printf("\n");
}
void getWord(char *string) {
char sentences[5][4];
int i;
int letter_counter = 0;
int word_counter = 0;
for (i = 0; i < strlen(string); i ++) {
// Checks if the character is a letter
if (isalpha(string[i])) {
sentences[word_counter][letter_counter] = string[i];
letter_counter++;
} else {
sentences[word_counter][letter_counter + 1] = '\0';
word_counter++;
letter_counter = 0;
}
}
// This is the code to see what it returns:
i = 0;
for (i; i < 5; i ++) {
int a = 0;
for (a; a < 4; a++) {
printf("%c", sentences[i][a]);
}
printf("\n");
}
}
int main() {
// This just returns the character array. No errors or problems here.
char *string = readFile("test.txt");
getWord(string);
return 0;
}
This is what it returns:
Hell
o
this
is
a) w
I suspect this has something to do with pointers and stuff. I come from a strong Java background so I'm still getting used to C.
With sentences[5][4] you're limiting the number of sentences to 5 and the length of each word to 4. You'll need to make it bigger in order to process more and longer words. Try sentences[10][10]. You're also not checking if your input words aren't longer than what sentences can handle. With bigger inputs this can lead to heap-overflows & acces violations, remember that C does not check your pointers for you!
Of course, if you're going to use this method for bigger files with bigger words you'll need to make it bigger or allocate it dymanically.
sample that do not use strtok:
void getWord(char *string){
char buff[32];
int letter_counter = 0;
int word_counter = 0;
int i=0;
char ch;
while(!isalpha(string[i]))++i;//skip
while(ch=string[i]){
if(isalpha(ch)){
buff[letter_counter++] = ch;
++i;
} else {
buff[letter_counter] = '\0';
printf("string[%d] = %s\n", word_counter++, buff);//copy to dynamic allocate array
letter_counter = 0;
while(string[++i] && !isalpha(string[i]));//skip
}
}
}
use strtok version:
void getWord(const char *string){
char buff[1024];//Unnecessary if possible change
char *p;
int word_counter = 0;
strcpy(buff, string);
for(p=buff;NULL!=(p=strtok(p, " ,."));p=NULL){//delimiter != (not isaplha(ch))
printf("string[%d] = %s\n", word_counter++, p);//copy to dynamic allocate array
}
}
i have written a program to reverse a string.. But it is not working.. It is printing the same string which is scanned.. What is the problem with the code?
#include <stdio.h>
#include <stdlib.h>
char *strrev(char *s)
{
char *temp = s;
char *result = s;
char t;
int l = 0, i;
while (*temp) {
l++;
temp++;
}
temp--;
for (i = 0; i < l; i++) {
t = *temp;
*temp = *s;
*s = t;
s++;
temp--;
}
return result;
}
int main()
{
char *str;
str = malloc(50);
printf("Enter a string: ");
scanf("%s", str);
printf("%s\n\n", strrev(str));
return 0;
}
for (i = 0; i < l; i++)
You're walking through the entire string, so you're reversing it twice - it won't be reversed after all. Walk only halfways:
for (i = 0; i < l / 2; i++)
Also, try using int len = strlen() instead of the while-not-end-of-string loop, if you're permitted to do so.
You swap the string's content twice.
Use the following code ..
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
char *strrev(char *s)
{
char *temp = s;
char *result = s;
char t;
while (*temp)
temp++;
while (--temp != s)
{
t = *temp;
*temp = *s;
*s++ = t;
}
return result;
}
int main()
{
char *str;
str = (char*)malloc(50);
printf("Enter a string: ");
scanf("%s", str);
printf("%s\n\n", strrev(str));
return 0;
}
The logic is to swap characters from start upto first half with the characters from last of second half, i.e, upto len/2. Just modify your for loop as below & it will work fine for you
for (i = 0; i < l/2; i++) {
you can use this simple code
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
int str_len (char *str)
{
char *ptr = str;
while (*str)
str++;
return str - ptr;
}
int main ()
{
char *str;
int length;
str = (char*)malloc(50);
printf("Enter a string: ");
scanf("%s", str);
length = str_len(str) - 1;
for (int i = length ; i >= 0 ; i--)
printf ("%c", str[i]);
return 0;
}
you can use this code to reverse the string
#include<stdio.h>
#include<string.h>
int main()
{
int n,i;
char str2[100],str1[100];
printf("enter teh string 1\n");
gets(str1);
n = strlen(str1);
for(i=0;i<n;i++)
{
str2[n-1-i]=str1[i];
}
printf("%s\n",str2);
}
Actually you are reversing the string twice...so after come to middle of the string, you should terminate the loop that is your loop should be run for half of the string length that is l/2 (in this case). so your loop should be like
for(i = 0; i < i / 2; i++)
swapping the string content twice..
swapping it once will help..
for (i = 0; i < l/2; i++)