Counting how many times the char sir2 appears in sequence sir1[] - c

I've got a problem with some chars and i can't figure out how to solve it. It is given a sequence of strings and another string. And I have to count the number of appearances of the string in the sequence of strings. I did the program below but it doesn't work.
main.cpp
#include "tipulbool.h"
char sir1[25], sir2;
int n, i, k;
int main (){
cin>>n;
for(i = 1; i <= n; i++)
cin>>sir1[i];
cin>>sir2;
for(i = 1; i <= n; i++)
k += secventa(sir1[i], sir2);
cout<<k;
return 0;
}
tipulbool.h
#include <iostream>
#include <string.h>
using namespace std;
int secventa (char sir1[], char sir2);
tipulbool.cpp
#include "tipulbool.h"
int secventa (char sir1[], char sir2){
int contor;
char *p;
p = strstr(sir1[], sir2);
if(p)
contor++;
while(p){
p = strstr(p + 1, sir2);
if(p)
contor++;
}
return contor;
}

try this:
int countOfChars(char sir1[], char sir2)
{
int count = 0;
char* p = sir1;
while (*p)
{
if (p == sir2)
{
++count;
}
++p;
}
return count;
}

this code:
#include "tipulbool.h"
int secventa (char sir1[], char sir2){
int contor;
char *p;
p = strstr(sir1[], sir2);
if(p)
contor++;
while(p){
p = strstr(p + 1, sir2);
if(p)
contor++;
}
return contor;
}
gets lost in it self.
suggest:
#include "tipulbool.h"
int secventa (char sir1[], char sir2){
int contor = 0;
char *p = str1;
while(NULL != (p = strchr(p, str2) ) )
{
contor++;
p++;
}
return contor;
}
However, note that
1) I used `strchr()` rather than `strstr()`
because `str2` is a single char, not a string
2) I removed the repetitive code
3) `str1` MUST be a NULL terminated string, which in the posted code is not the case.
regarding this code:
#include "tipulbool.h"
char sir1[25], sir2;
int n, i, k;
int main (){
cin>>n;
for(i = 1; i <= n; i++)
cin>>sir1[i];
cin>>sir2;
for(i = 1; i <= n; i++)
k += secventa(sir1[i], sir2);
cout<<k;
return 0;
}
in C++, an array offset starts with 0 and continues to (length of array -1)
variables that are only used in a single function should (in general) be defined as local/auto variables within that function.
suggest using code similar to the following:
#include "tipulbool.h"
int main ( void )
{
char sir2;
int n; // will contain number of char in str1
int i; // loop counter
int k = 0; // will contain number of occurrence of str2 in str1
// get count of chars in first string
cin >> n;
// allocate room for first string (using C string)
// +1 to allow for NUL terminator byte
char *sir1 = new char[n+1];
// initialize first string
memset( sir1, 0x00, n+1 );
// input first string
for(i = 0; i < n; i++)
cin >> sir1[i];
// input target char
cin >> sir2;
// get count of occurances of str2 in str1
k = secventa(sir1, sir2);
cout << k << endl;
delete [] str1;
return 0;
}
Since this is C++, you might want to look at vector or string
to simplify the written part of the code even further

Related

Not getting output from string array function in c

I was making a split function in C to use its return value in some programs. But when I checked its value using printf, I discovered that there are some errors but I was unable to fix them myself. I fixed most of the errors I could.
The code I wrote is:
#include <stdio.h>
#include <string.h>
char **split(char *token, char *delimiter, int *a[], int *size_of_a) {
int i = 0;
char **final_result;
char *str = strtok(token, delimiter);
while (str != NULL) {
*a[i] = strlen(str); //maybe one of the errors but I don't know how to fix it
//even after removing a[i] by backslash and changing it in loop and main, there is still no output received in main
getch();
for (int j = 0; j < *a[i]; j++) {
final_result[i][j] = str[j];
}
str = strtok(NULL, delimiter);
i++;
}
*size_of_a = i;
return final_result;
}
int main() {
char *parameter_1;
char *parameter_2;
int *size_1;
int size_2;
printf("Enter the token: ");
scanf("%s", &parameter_1);
printf("\nEnter the delimiter: ");
scanf("%s", &parameter_2);
char **result_2 = split(parameter_1, parameter_2, &size_1, &size_2);
printf("\nThe result is:");
for (int x = 0; x < size_2; x++) {
printf('\n');
for (int y = 0; y < size_1[x]; y++) {
printf("%c", result_2[x][y]);
}
}
getch();
return 0;
}
How can I fix the output error?
There are multiple problems in the code:
You do not allocate space for the array of pointers: final_result is uninitialized, storing anything via dereferencing it has undefined behavior, most likely a segmentation fault.
You should use strcpn() and strspn() to compute the number of tokens, allocate the array with or without an extra slot for a NULL terminator and perform a second phase splitting the tokens and storing the pointers to the array. You might want to store copies of the tokens to avoid modifying the original string that may be constant or go out of scope.
printf('\n'); is invalid: you must pass a string, not a character constant.
scanf("%s", &parameter_1); also has undefined behavior: you pass the address of a pointer instead of a pointer to an array of char.
Here is a modified version:
#ifdef _MSC_VER
#define _CRT_SECURE_NO_WARNINGS
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef _MSC_VER
// define POSIX function strndup if not available
char *strndup(const char *s, size_t n) {
size_t len;
for (len = 0; len < n && s[len]; len++)
continue;
char *ptr = malloc(len + 1);
if (ptr) {
memcpy(ptr, s, len);
ptr[len] = '\0';
}
return ptr;
}
#endif
char **split(const char *str, const char *delimiters, int **a, int *size_of_a) {
int i, count, len;
char **final_result;
const char *p;
// phase 1: count the number of tokens
p = str + strspn(str, delimiters);
for (count = 0; *p; count++) {
p += strcspn(p, delimiters);
p += strspn(p, delimiters);
}
// phase 2: allocate the arrays
final_result = calloc(sizeof(*final_result), count + 1);
if (a) {
*a = calloc(sizeof(**a), count);
}
if (size_of_a) {
*size_of_a = count;
}
// phase 3: copy the tokens
p = str;
for (i = 0; i < count; i++) {
p += strspn(p, delimiters); // skip the delimiters
len = strcspn(p, delimiters); // count the token length
if (a) {
(*a)[i] = len;
}
final_result[i] = strndup(p, len); // duplicate the token
p += len;
}
final_result[count] = 0;
return final_result;
}
// read and discard the rest of the user input line
int flush_input(void) {
int c;
while ((c = getchar()) != EOF && c != '\n')
continue;
return c;
}
int main() {
char buf[256];
char delimiters[20];
printf("Enter the string: ");
if (scanf("%255[^\n]", buf) != 1)
return 1;
flush_input();
printf("\nEnter the delimiters: ");
if (scanf("%19[^\n]", delimiters) != 1)
return 1;
flush_input();
int *sizes;
int count;
char **array = split(buf, delimiters, &sizes, &count);
printf("\nThe result is:\n");
for (int x = 0; x < count; x++) {
for (int y = 0; y < sizes[x]; y++) {
putchar(array[x][y]);
}
printf("\n");
}
getchar();
return 0;
}

Every k-th digit cyclic problem using strings in C

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

segmentation fault when calling c function on ruby

I am trying to extends my Ruby code with a C functions. The C code compiles without warning. But When I try to run the ruby code, I got a segmentation fault:
I have this c code:
#include <ruby.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "nessie.h"
/* #define TRACE_INTERMEDIATE_VALUES */
/*
* The number of rounds of the internal dedicated block cipher.
*/
#define R 10
VALUE rb_mExample;
VALUE rb_cClass;
// ...
static char* displayHash(const unsigned char array[], int length){
int i, k;
char *str;
str = malloc(3 * length + 1);
if (str == NULL) {
return NULL;
}
k = 0;
str[0] = '\0';
for (i = 0; i < length; i++){
char hex[3];
if (i % 32 == 0){
str[k++] = ' ';
}
if (i % 8 == 0){
str[k++] = ' ';
}
snprintf(hex, sizeof(hex), "%02X", array[i]);
str[k++] = hex[0];
str[k++] = hex[1];
}
str[k] = '\0';
return str;
}
VALUE
print_string(VALUE class, VALUE *valor) {
struct NESSIEstruct w;
u8 digest[DIGESTBYTES];
int i;
for (i = 0; valor[i] != '\0'; i++);
int sizeo = i;
NESSIEinit(&w);
NESSIEadd((u8*)valor, 8*sizeo, &w);
NESSIEfinalize(&w, digest);
return (VALUE) displayHash(digest, DIGESTBYTES);
}
void
Init_example(){
rb_mExample = rb_define_module("Example");
rb_cClass = rb_define_class_under(rb_mExample, "Class", rb_cObject);
rb_define_method(rb_cClass, "print_string", print_string, 1);
}
and this Ruby code:
require "example"
def print
e = Example::Class.new
e.print_string("ruby")
end
When I run the ruby code, I got a segmentation fault.
EDIT: gist with log info
https://gist.github.com/psantos10/f07484afa26ce0e55181
Where I failing? I am new in C language.
EDIT:
I changed my "print_string" to look like this:
VALUE
print_string(VALUE class, VALUE *valor) {
struct NESSIEstruct w;
u8 digest[DIGESTBYTES];
int i;
for (i = 0; valor[i] != '\0'; i++);
int sizeo = i;
NESSIEinit(&w);
NESSIEadd((u8*)valor, 8*sizeo, &w);
NESSIEfinalize(&w, digest);
return rb_str_new(displayHash(digest, DIGESTBYTES), 128);
}
whith that, segmentation fault gone. But the string returned is coming with a strange characters like:
"ruby\x00\x00\x00\x00\x00No error detected.\x00\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xD80x\xC0\x18`\x18\x18&F\xAF\x05#\x8C##\xB8\x91\xF9~\xC6?\xC6\xC6\xFB\xCDo\x13\xE8\x87\xE8\xE8\xCB\x13\xA1L\x87&\x87\x87\x11mb\xA9\xB8\xDA\xB8\xB8\t\x02\x05\b\x01\x04\x01\x01\r\x9EnBO!OO\x9Bl\xEE\xAD6\xD866\xFFQ\x04Y\xA6\xA2\xA6\xA6\f\xB9\xBD\xDE\xD2o\xD2"
When the correct must be only:
"ruby"
EDIT 3:
Making this change:
VALUE
print_string(VALUE class, VALUE *valor) {
struct NESSIEstruct w;
u8 digest[DIGESTBYTES];
/*
int i;
for (i = 0; valor[i] != '\0'; i++);
int sizeo = i;
*/
NESSIEinit(&w);
NESSIEadd((u8*)"ruby", 8*4, &w);
NESSIEfinalize(&w, digest);
return rb_str_new(displayHash(digest, DIGESTBYTES), 128);
}
the correct value are returned.
Then I try to to that:
VALUE
print_string(VALUE class, VALUE *valor) {
struct NESSIEstruct w;
u8 digest[DIGESTBYTES];
/*
int i;
for (i = 0; valor[i] != '\0'; i++);
int sizeo = i;
*/
NESSIEinit(&w);
NESSIEadd((u8*)"ruby", 8*4, &w);
NESSIEfinalize(&w, digest);
return rb_str_new2(valor);
}
Expecting "ruby" string to be returned. But not. It returns: "\x05"
What that mean?
for (i = 0; i < length; i++)
Inside this loop for each passing if condition you increment k so by doing this you will be having array out of bound access hence the crash.
Make sure the
char *str = malloc( 3 * length + 1);
is not
char *str = malloc( 3 * (length + 1));
For Eg:
Have value of length = 2;
char *str = malloc(7);
Now in the for loop you increment k 4 times.
k = 4;
Now after the second iteration if you exit the loop then
k=8;
So str[8] is not a valid access and might lead to crash
Before all, let me thanks #FrederickCheung for give me the right direction.
The solution code is:
VALUE
print_string(VALUE class, VALUE valor) {
struct NESSIEstruct w;
u8 digest[DIGESTBYTES];
VALUE info;
// Note here I must convert the Ruby VALUE type to C type. Thats is the trick.
char* valor2 = RSTRING_PTR(valor);
int i;
for (i = 0; valor2[i] != '\0'; i++);
int sizeo = i;
NESSIEinit(&w);
NESSIEadd((u8*)valor2, 8*sizeo, &w);
NESSIEfinalize(&w, digest);
info = rb_str_new_cstr(displayHash(digest, DIGESTBYTES));
return info;
}
For who want to see where this code was used, can access: https://github.com/AngoDev/kryptonita

C - strcat in for loop

I m writing a little C program and want to know why my output in the console is "0", "0" [...]? The output i expect is "ab", "ac", [...].
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[])
{
int i;
int j;
char string[] = "abc";
char output[8];
int length = size(&string[0]);
for(i=0; i<length; i++) {
for(j=0; j<length; j++){
char a = string[i];
strcat(output, &a);
char b = string[j];
strcat(output, &b);
printf("%c\n", output);
}
}
return 0;
}
Mistake #1. You have not initialised output[] so strcat() will not validly find a nul terminator to append to.
output[0] = 0;
Mistake #2. strcat() isn't the right way of appending chars anyway.
Mistake #3. Your loop controls aren't right. See below.
Mistake #4. Your length is the size of a char* pointer.
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[])
{
int i, j;
char string[] = "abc";
char output[8];
int length = strlen (string); // corrected
for(i=0; i<length-1; i++) { // amended loop
for(j=i+1; j<length; j++) { // amended loop
output[0] = string [i];
output[1] = string [j];
output[2] = 0; // string terminator
printf("%s\n", output); // uses string type not char
}
}
return 0;
}
Program output:
ab
ac
bc
If I have understood correctly what you are trying to do then the program will look the following way
#include <stdio.h>
int main(int argc, char *argv[])
{
char string[] = "abc";
char output[3];
size_t length = sizeof( string ) - 1;
for ( size_t i = 0; i < length; i++ )
{
for ( size_t j = 0; j < length; j++ )
{
if ( i != j )
{
output[0] = string[i];
output[1] = string[j];
output[2] = '\0';
puts( output );
}
}
}
return 0;
}
The output is
ab
ac
ba
bc
ca
cb
If your compiler does not allow to declare variables within the control statement of the loop then you can declare i and j in the beginning of the program.
size_t i, j;
If you want to include combinations like "aa" then you simply may remove the if statement withing the inner loop.
char a = string[i];
strcat(output, &a);
leads to undefined behavior since strcat expects a null terminated string in the second argument. Same thing applies to:
char b = string[j];
strcat(output, &b);
Perhaps you meant to use:
output[0] = a;
output[1] = b;
output[2] = '\0';
Here's the updated for loop:
for(i=0; i<length; i++) {
for(j=0; j<length; j++){
output[0] = a;
output[1] = b;
output[2] = '\0';
printf("%s\n", output);
// ^^ use %s to print a string, not %c.
}
}
If you want to use strcat you must know that it expects a string not a character and there is an important difference, when you pass &a strcat thinks it is the address of a pointer to a string, and you should get most likely a segmentation fault, here I show your own code, modified to use strcat but you don't really need it for this task.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[])
{
int i;
int j;
char string[] = "abc";
int length = strlen(&string[0]);
for(i = 0 ; i < length ; i++)
{
for(j= i + 1 ; j < length ; j++)
{
/* initialize output to 0 more importantly to have a terminating null byte */
char output[3] = {0};
/*
* create a string and initialize it with 2 char's
* - the first one, the one you want to append to output
* - the second one is required by strcat, to mark the end of the string
*/
char a[2] = {string[i], 0};
strcat(output, a);
/* same as above */
char b[2] = {string[j], 0};
strcat(output, b);
printf("%s\n", output);
}
}
return 0;
}
you could do this without strcat unless you are trying to learn how to use strcat, this is an example of how to do it without strcat.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[])
{
int i;
int j;
char string[] = "abc";
int length = strlen(&string[0]);
for(i = 0 ; i < length ; i++)
{
for(j= i + 1 ; j < length ; j++)
{
char output[3] = {string[i], string[j], 0};
printf("%s\n", output);
}
}
return 0;
}

How to write a getline function in C?

I know that getline is C++ standard but I need to read a line of digits:
123856
and save it to an array. But how to do this without spaces between given (as input) digits? I want a user input to be:
123856 (with no spaces) and then save it to an array (n element array) and after that, I want my array to look like this:
array[0] = 1;
array[1] = 2;
array[2] = 3;
array[3] = 8;
array[4] = 5;
array[5] = 6;
But how to make it in C, without a getline?
This is NOT what I want:
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdbool.h>
int main(int argc, char **argv)
{
int t[4];
int i;
for(i=0; i<4; i++)
scanf("%d", &t[i]);
for(i=0; i<4; i++)
printf("%d\n", t[i]);
return 0;
}
If I understood you correct, the following should do it:
read the whole line
loop through the string as long as you get digits or the string ends
for every digit, place it's value in your array and increase the index by 1
while( ( c = getchar()) != EOF && c != '\n' && i < max ) {
/* If desired, add check for value outside of 0-9 */
array[ i++ ] = c - '0';
...
}
char arr[] = "1234567";
int intarr[10];
int count = 0;
for (char* ptr = arr; *ptr; ptr++) {
intarr[count] = *ptr - '0';
count++;
}
try this
#include <stdio.h>
#include <string.h>
main (int argc, char *argv[])
{
FILE *f;
int i=0;
int j=0;
char output[100];
char* output1[100];
char string[100];
char delims1[] = " ";
char delims2[] = "*";
char* result = NULL;
char* result3 = NULL;
int num;
//for (j=0; j<2; j++)
//{
//printf("%s",delims9[6]);
//}
f = fopen("text.txt","r");
//
while( fgets(string,sizeof(string),f) )
{
result = strtok( string, delims1 );
while( result != NULL )
{
output1[i]=result;
printf("%s\n",output1[i]);
result = strtok( NULL, delims1 );
i++;
}
for (num = 0; num < 100; i++ ) //
{ // Error On this array
printf("%s\n", output1[i]); //
} //
}
printf("\n%d",i/3+1);
return 0 ;
}
Ok, without using any string.
int digits = 123856;
int numofdigits = 1 + floor(log10(digits));
int digits_arr[numofdigits];
int i;
for(i = numofdigits-1; i >= 0; i--) {
digits_arr[i] = (int)floor(digits / pow(10, i)) % 10;
}
Try the below link... Same question asked here and get solution....
convert an integer number into an array
char * convertNumberIntoArray(unsigned int number) {
unsigned int length = (int)(log10((float)number)) + 1;
char * arr = (char *) malloc(length * sizeof(char)), * curr = arr;
do {
*curr++ = number % 10;
number /= 10;
} while (number != 0);
return arr;
}

Resources