How to add text_view scroll on gtk? - c

I have added txtview by using this function >>
text_v = gtk_text_view_new()
bt here scroll is not working and also how to set textview size, have used this one =>>
gtk_widget_set_size_request(text_v,400,200);
bt is also not working

This is the way I did it :
#include<gtk/gtk.h>
int main(int argc, char* argv[])
{
GtkWidget *textview, *window, *scrolledwindow;
GtkTextBuffer *buffer;
gtk_init(&argc, &argv); /*void gtk_init (int *argc,char ***argv);*/
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gchar* sample_text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit,\n" \
"sed do eiusmod tempor incididunt ut labore et dolore magna\n" \
"aliqua. Ut enim ad minim veniam, quis nostrud exercitation\n" \
"ullamco laboris nisi ut aliquip ex ea commodo consequat.\n"\
"Duis aute irure dolor in reprehenderit in voluptate velit\n"\
"esse cillum dolore eu fugiat nulla pariatur. Excepteur sint\n"\
"occaecat cupidatat non proident, sunt in culpa qui officia\n"\
"deserunt mollit anim id est laborum.";
textview = gtk_text_view_new();
gtk_widget_set_size_request(textview, 400, 200); // This is but a request. The sizes are not guaranteed.
scrolledwindow = gtk_scrolled_window_new(NULL, NULL);
buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview));
gtk_text_buffer_set_text(buffer, sample_text, -1);
gtk_container_add(GTK_CONTAINER(scrolledwindow), textview);
gtk_container_add(GTK_CONTAINER(window), scrolledwindow);
gtk_widget_show_all(window);
gtk_main();
return 0;
}
If you need to customize the scroll window it is worth having a look here.

Related

C - print from a pointer in the buffer

Working on a CS class - C course problem. Part of the problem is to create a function to print the specified length from a char buffer, given a char pointer to print from.
Signature of the function to be called in loop:
bool printLine(char cbuffer, char *ptr, int bufferFillLength)
where cbuffer is the pointer to the beginning of the buffer, ptr is the pointer to the start of the string to print. Variable bufferFillLength is the number of characters to print from the buffer starting at ptr.
The function should be called in loop until the end of the line is reached (i.e function returns false).
Here is my attempt but not working and looking for help.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#define BUFFER_SIZE 300
bool printLine (char cbuffer, char *ptr, int printLength){
char *bufferprinttext;
strncpy (bufferprinttext, &cbuffer[ptr], printLength);
printf("%s", bufferprinttext);
if(bufferprinttext[strlen(bufferprinttext)-1] == '\n') {
//end of line reasched - return false;
return false;
}
return true;
}
int main(int argc, char *argv[])
{
char cbuffer[BUFFER_SIZE];
int printLength = 25;
bool isItEndOfBuffer = false;
int bufferCounter = 0;
cbuffer = "Fusce dignissim facilisis ligula consectetur hendrerit. Vestibulum porttitor aliquam luctus. Nam pharetra lorem vel ornare condimentum. Praesent et nunc at libero vulputate convallis. Cras egestas nunc vitae eros vehicula hendrerit. Pellentesque in est et sapien dignissim molestie.";
while(isItEndOfBuffer == false) {
++bufferCounter;
isItEndOfBuffer = printLine(cbuffer, &cbuffer[printLength * bufferCounter], printLength);
}
}
cbuffer is not a pointer as you say but is passed by value, thus you are not holding it's original reference as you seem to want. Try with the signature
bool printLine (char *cbuffer, char *ptr, int printLength);
Jonathan Leffler: I have update the code per your comment. The function prints now but truncated at the beginning. Couldn't figure out what I am missing.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#define BUFFER_SIZE 300
bool printLine (char cbuffer, char *ptr, int printLength){
for (int i = 0; i < printLength; i++) {
putchar(*ptr++);
if(*ptr == '\0') {
//end of line reasched - return false;
return true;
}
}
return false;
}
int main(int argc, char *argv[])
{
int printLength = 25;
bool isItEndOfBuffer = false;
int bufferCounter = 0;
char* cbuffer = "Fusce dignissim facilisis ligula consectetur hendrerit. Vestibulum porttitor aliquam luctus. Nam pharetra lorem vel ornare condimentum. Praesent et nunc at libero vulputate convallis. Cras egestas nunc vitae eros vehicula hendrerit. Pellentesque in est et sapien dignissim molestie.";
//printf ("cbuffer - start ptr=%p \n", &cbuffer[0]);
printf("Text to print:\n %s \n\n", cbuffer);
printf("But text is truncated at the begining by printLength(i.e. 25): \n");
//printf ("\nisItEndOfBuffer=%d \n", isItEndOfBuffer );
while( !isItEndOfBuffer ) {
++bufferCounter;
//printf ("ptr=%p \n", &cbuffer[printLength * bufferCounter]);
isItEndOfBuffer = printLine(*cbuffer, &cbuffer[printLength * bufferCounter], printLength);
//printf ("\nisItEndOfBuffer=%d \n", isItEndOfBuffer );
}
}
Output:
Text to print:
Fusce dignissim facilisis ligula consectetur hendrerit. Vestibulum porttitor aliquam luctus. Nam pharetra lorem vel ornare condimentum. Praesent et nunc at libero vulputate convallis. Cras egestas nunc vitae eros vehicula hendrerit. Pellentesque in est et sapien dignissim molestie.
But text is truncated at the begining by printLength(i.e. 25):
ligula consectetur hendrerit. Vestibulum porttitor aliquam luctus. Nam pharetra lorem vel ornare condimentum. Praesent et nunc at libero vulputate convallis. Cras egestas nunc vitae eros vehicula hendrerit. Pellentesque in est et sapien dignissim molestie.

How to fix this code so that it shuffles letters and has no affect on first letter and last letter, punctuation

I'm dealing with go/golang, trying to write code that takes a string and seed. It should return a shuffled string where the 1st and last letters in the word, punctuation and numbers are untouched.
Example:
my name is Nikki. My number is 333
should be
my nmae is Nkiki. My nebumr is 333
I'm very new to goland/go. Have tried to do it with rand.Shuffle:
func splitText(text string) []string {
re := regexp.MustCompile("[A-Za-z0-9']+|[':;?().,!\\ ]")
return re.FindAllString(text, -1)}
func scramble(text string, seed int64) string {
rand.Seed(seed)
split := splitText(text)
for i := range split {
e := split[i]
r := []byte(e)
for i := 0; i < len(r); i++ {
l := len(r) - 1
if i == 0 {
return string(r[0])
}
if i == l {
return string(r[l])
}
if i > 0 || i < l {
n := rand.Intn(l)
x := r[i]
r[i] = r[n]
r[n] = x
}
if (r[i] >= 32 && r[i] <= 62) || (r[i] >= 91 && r[i] <= 96) {
return string(r[i])
}
}
}
return text
}
func main() {
v := ("The quick brown fox jumps over the lazy dog.")
scramble(v, 100)
fmt.Println(scramble(v, 100))
}
But this returns only one letter and only if remoe f==0 or f==l, it doesn't hop to the next word.
I'm very new to goland/go.
Avoid writing programs in a new language as if you are still writing programs in an old language.
write code that takes a string and seed. It should return a shuffled
string where the 1st and last letters in the word, punctuation and
numbers are untouched.
Example:
my name is Nikki. My number is 333
should be
my nmae is Nkiki. My nebumr is 333
Here is a solution written in Go.
package main
import (
"fmt"
"math/rand"
"unicode"
)
func shuffle(word []rune, rand *rand.Rand) {
if len(word) < 4 {
return
}
chars := word[1 : len(word)-1]
rand.Shuffle(
len(chars),
func(i, j int) {
chars[i], chars[j] = chars[j], chars[i]
},
)
}
func scramble(text string, seed int64) string {
rand := rand.New(rand.NewSource(seed))
chars := []rune(text)
inWord := false
i := 0
for j, char := range chars {
if !unicode.IsLetter(char) {
if inWord {
shuffle(chars[i:j], rand)
}
inWord = false
} else if !inWord {
inWord = true
i = j
}
}
if inWord {
shuffle(chars[i:len(chars)], rand)
}
return string(chars)
}
func main() {
for _, text := range []string{
"my name is Nikki. My number is 333",
"The quick brown fox jumps over the lazy dog.",
loremipsum,
} {
fmt.Printf("%q\n", text)
fmt.Printf("%q\n", scramble(text, 100))
}
}
var loremipsum = `
Lorem ipsum dolor sit amet, consectetur adipiscing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident,
sunt in culpa qui officia deserunt mollit anim id est laborum.
`
Playground: https://play.golang.org/p/NoHXynQSD4p
Output:
"my name is Nikki. My number is 333"
"my name is Nkiki. My neubmr is 333"
"The quick brown fox jumps over the lazy dog."
"The quick bowrn fox jmups over the lzay dog."
"\nLorem ipsum dolor sit amet, consectetur adipiscing elit, \nsed do eiusmod tempor incididunt ut labore et dolore magna aliqua. \nUt enim ad minim veniam, \nquis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. \nDuis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. \nExcepteur sint occaecat cupidatat non proident, \nsunt in culpa qui officia deserunt mollit anim id est laborum.\n"
"\nLorem isupm dloor sit amet, csttunoecer andiipcsig elit, \nsed do emiousd tepmor idinicdnut ut lorbae et dorloe mgnaa aqilua. \nUt einm ad miinm vinaem, \nquis notursd eioattxceirn ualmlco libroas nisi ut aqiiulp ex ea cdmoomo cuanqesot. \nDius aute iurre dolor in rienreehredpt in vlptuotae vielt esse clulim drlooe eu fuagit nulla ptaaiurr. \nEepuxcter snit ocecacat citapadut non prinodet, \nsnut in cpula qui oficfia dsuenret milolt ainm id est laorbum.\n"

Split a char array in multiple parts in C: unexpected behaviour

As a student with a background in Java, C#, a bit of Python and web-based languages, I am currently learning C. For practice I am coding a GTK application to convert a longer text to smaller pieces of text of 140 characters max. This use case is meant to post longer texts on Twitter easily.
So I experimented a bit and the application is working more or less at this moment. However, it regularly shows unexpected behaviour. When inserting text in the GTK interface (TextView) and clicking a button calling the below method, the output put back into the TextView sometimes looks like this:
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut eni
(1/4)
m ad minim veniam, quis nostrud exercitation ullamco laboris
nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in rep
(2/4)
(0/1981836649)
rehenderit in voluptate velit esse cillum dolore
eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
proident, sunt in (3/4)
(0/1763734633)
(1701998412/544044403)
culpa qui officia deserunt mollit anim id est laborum. (4/4)
Or similar when inserting Lorem Ipsum as input. Sometimes it also cuts an entire part (e.g., only the (4/4) part is printed). The expected output is:
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut eni (1/4)
m ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip > ex ea commodo consequat. Duis aute irure dolor in rep (2/4)
rehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident, sunt in (3/4)
culpa qui officia deserunt mollit anim id est laborum. (4/4)
It applies to the following method, which is hooked to a GTK button:
void on_do_tweet_clicked()
{
char *text = get_text_from_text_view(g_tv_tweet_text);
int text_length = strlen(text);
int tweet_no = text_length / 130 + (text_length % 130 != 0);
char tweets[(int) tweet_no][140 * sizeof(char*)];
for (int i = 0; i < tweet_no; i++)
{
char *tweet = (char*) malloc(sizeof(char*) * 140);
if (tweet_no != 1) {
if (i + 1 == tweet_no) {
strcpy(tweet, &text[i * 130]);
} else {
strncpy(tweet, &text[i * 130], 130);
}
strcat(tweet, " (%d/%i)\n\0");
sprintf(tweets[i], tweet, i + 1, tweet_no);
} else {
strcpy(tweet, &text[i * 130]);
sprintf(tweets[i], tweet);
}
free(tweet);
}
free(text);
GtkTextBuffer *buffer = gtk_text_view_get_buffer((GtkTextView *) g_tv_tweet_text);
gtk_text_buffer_set_text(buffer, "", 0);
for (int i = 0; i < sizeof(tweets) / sizeof(tweets[0]); i++)
{
gtk_text_buffer_insert_at_cursor(buffer, tweets[i], strlen(tweets[i]));
}
memset(tweets, 0, sizeof(tweets));
}
I did some research on the problem and I suspect it has to do with either an problem with encodings or a problem related to pointers. However, my searches on the web did not result in a solution and my knowledge of C is still too limited to draw my own conclusions.
So here's the question: could anyone explain why this method is showing this behaviour and give me a hint on how to solve it?
Thank you in advance!
Thanks to #AnT I got it working. The final code is:
void on_do_tweet_clicked()
{
char *text = get_text_from_text_view(g_tv_tweet_text);
int text_length = strlen(text);
int tweet_no = text_length / 130 + (text_length % 130 != 0);
char tweets[(int) tweet_no][140 * sizeof(char)];
for (int i = 0; i < tweet_no; i++)
{
char *tweet = (char*) malloc(sizeof(char) * 140);
if (tweet_no != 1) {
if (i + 1 == tweet_no) {
strcpy(tweet, &text[i * 130]);
} else {
strncpy(tweet, &text[i * 130], 130);
}
tweet[130] = '\0';
strcat(tweet, " (%d/%i)\n");
sprintf(tweets[i], tweet, i + 1, tweet_no);
} else {
strcpy(tweets[i], &text[i * 130]);
}
free(tweet);
}
free(text);
GtkTextBuffer *buffer = gtk_text_view_get_buffer((GtkTextView *) g_tv_tweet_text);
gtk_text_buffer_set_text(buffer, "", 0);
for (int i = 0; i < sizeof(tweets) / sizeof(tweets[0]); i++)
{
gtk_text_buffer_insert_at_cursor(buffer, tweets[i], strlen(tweets[i]));
}
memset(tweets, 0, sizeof(tweets));
}

Bubble Sort leaves array empty

I'm trying to sort an array of characters in C. My bubble sort algorithm is a standard one but when I try to print the arrays after using the sort method they appear to be empty.
Is this a problem with my pointer usage?
#include <stdio.h>
#include <string.h>
char Gstr1[256];
char Gstr2[256];
void load();
void printArrays();
void sortArray(char *array);
main()
{
load();
printArrays();
sortArray(&Gstr1[0]);
sortArray(&Gstr2[0]);
printf("\n\n");
printArrays();
}
void load()
{
memcpy (Gstr1,"Sed aliquam neque fermentum leo semper sagittis. Curabitur imperdiet, libero vulputate laoreet tristique, magna justo posuere, quis rutrum ligula tortor vitae eros. Phasellus sed dignissim elit, nec dictum ligula. Vivamus ornare ultrices odio eget dictum.",255);
memcpy (Gstr2,"Lorem ipsum dolor si amet, consectetur adipiscing elit. Aenean dapibus libero a convallis sodales. Mauris placerat nisl leo, vitae tincidunt turpis tristique in. Pellentesque vehicula nisl vitae efficitur ornare. Nunc imperdiet sem, in aliquam rhoncus at.",255);
}
void printArrays()
{
printf(Gstr1);
printf("\n\n");
printf(Gstr2);
}
void sortArray(char *array)
{
int i,j;
char temp;
for(i=0;i<(256-1);i++)
for(j=0;j<(256-i-1);j++)
{
if((int)*(array+j)>(int)*(array+(j+1)))
{
temp=*(array+j);
*(array+j)=*(array+(j+1));
*(array+(j+1))=temp;
}
}
}
This is because of the string length. The length of first string is 256 and second is 257, and you're not taking care of '\0' character. Hence, it is advisable to use memcpy_s() instead of memcpy() and also, use strlen() instead of hardcoding the array size in the for loops. However, with minor correction of the for loop limit, the following code produces the output.
Code:
#include <stdio.h>
#include <string.h>
char Gstr1[256];
char Gstr2[256];
void load();
void printArrays();
void sortArray(char *array);
main()
{
load();
printArrays();
sortArray(&Gstr1[0]);
sortArray(&Gstr2[0]);
printf("\n\n");
printArrays();
}
void load()
{
memcpy (Gstr1,"Sed aliquam neque fermentum leo semper sagittis. Curabitur imperdiet, libero vulputate laoreet tristique, magna justo posuere, quis rutrum ligula tortor vitae eros. Phasellus sed dignissim elit, nec dictum ligula. Vivamus ornare ultrices odio eget dictum.",255);
memcpy (Gstr2,"Lorem ipsum dolor si amet, consectetur adipiscing elit. Aenean dapibus libero a convallis sodales. Mauris placerat nisl leo, vitae tincidunt turpis tristique in. Pellentesque vehicula nisl vitae efficitur ornare. Nunc imperdiet sem, in aliquam rhoncus at.",255);
}
void printArrays()
{
printf(Gstr1);
printf("\n\n");
printf(Gstr2);
}
void sortArray(char *array)
{
int i,j;
char temp;
for(i=0;i<strlen(array);i++)
for(j=0;j<(strlen(array)-i-1);j++)
{
if((int)*(array+j)>(int)*(array+(j+1)))
{
temp=*(array+j);
*(array+j)=*(array+(j+1));
*(array+(j+1))=temp;
}
}
}
You sort the last character in the array as well resulting in a sorted character array with leading null terminator.
Therefore just adjust your loops to fix your issue as shown below.
Of course it would be better to pass the array size with a parameter but that's a different topic :)
void sortArray(char *array)
{
int i,j;
char temp;
for(i=0;i<(256-2);i++)
for(j=0;j<(256-i-2);j++)
{
if((int)*(array+j)>(int)*(array+(j+1)))
{
temp=*(array+j);
*(array+j)=*(array+(j+1));
*(array+(j+1))=temp;
}
}
}

Remove first line from text file in Golang

I'm trying to pop the first line of a file and thus reduce the file lines one by one.
My implementation for removing the first line is as follows
type FS struct {
...
File *os.File
}
//File creation ok...
func (fs *Fs) pop() []byte {
var buf []string
scanner := bufio.NewScanner(fs.File)
//Reading lines
for scanner.Scan() {
line := scanner.Text()
buf = append(buf, line)
}
//Writing from second line on the same file
for s := 1; s < len(buf); s++ {
fs.File.WriteString(fmt.Println(buf[s]))
}
//Commit changes
fs.File.Sync()
fs.File.Close()
return []byte(buf[0])
}
I get the returned []byte with the expected string but the file never changes.
What am I missing here?
pop the first line of a file and thus reduce the file lines one by
one.
For example,
package main
import (
"bytes"
"fmt"
"io"
"os"
)
func popLine(f *os.File) ([]byte, error) {
fi, err := f.Stat()
if err != nil {
return nil, err
}
buf := bytes.NewBuffer(make([]byte, 0, fi.Size()))
_, err = f.Seek(0, io.SeekStart)
if err != nil {
return nil, err
}
_, err = io.Copy(buf, f)
if err != nil {
return nil, err
}
line, err := buf.ReadBytes('\n')
if err != nil && err != io.EOF {
return nil, err
}
_, err = f.Seek(0, io.SeekStart)
if err != nil {
return nil, err
}
nw, err := io.Copy(f, buf)
if err != nil {
return nil, err
}
err = f.Truncate(nw)
if err != nil {
return nil, err
}
err = f.Sync()
if err != nil {
return nil, err
}
_, err = f.Seek(0, io.SeekStart)
if err != nil {
return nil, err
}
return line, nil
}
func main() {
fname := `popline.txt`
f, err := os.OpenFile(fname, os.O_RDWR|os.O_CREATE, 0666)
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
defer f.Close()
line, err := popLine(f)
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
fmt.Println("pop:", string(line))
}
$ cat popline.txt
Lorem ipsum dolor sit amet, consectetur adipiscing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident,
sunt in culpa qui officia deserunt mollit anim id est laborum.
$ go run popline.go
pop: Lorem ipsum dolor sit amet, consectetur adipiscing elit,
$ cat popline.txt
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident,
sunt in culpa qui officia deserunt mollit anim id est laborum.
$

Resources