Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.62/29: Рейтинг темы: голосов - 29, средняя оценка - 4.62
0 / 0 / 0
Регистрация: 18.01.2015
Сообщений: 5
1

Сдвинуть буквы, в каждом слове, влево или вправо, на n символов

18.01.2015, 09:14. Просмотров 6007. Ответов 9
Метки нет (Все метки)

Задача: Взять из файла текст (слова, разделённые знаками препинания и пробелами) и сдвинуть буквы, в каждом слове, влево или вправо, на n символов. Результат записать в файл. Собственно c++ изучаю примерно один день

Пока что у меня один вопрос - как считать файл в массив? Взять весь текст, как один массив, где каждое слово - элемент. И сдвигать буквы в каждом элементе (если это возможно)? Или другой вариант - взять каждое слово, как массив, а буквы, как элементы (и соотв. сдвигать элементы) и как это реализовать. Пользуюсь visual studio express 2013, если это имеет значение.
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
18.01.2015, 09:14
Ответы с готовыми решениями:

Сдвинуть букву в слове на одну позицию влево/вправо
Здравствуйте. Как можно реализовать код, что бы допустим слово privet превращало в rpvite ?

Сдвинуть массив на k элементов вправо и влево
Вправо сдвинул, а влево - выход за пределы массива //Циклически сдвинуть массив вправо и влево...

Нужно сдвинуть число на 4 разряда влево и вправо
Нужно сдвинуть 1000 на 4 разряда влево и вправо. Тема указатели. Препод говорил, что число нужно...

Сдвинуть элементы на одну позицию вправо\влево
Ребята помогите пожалуйста с решением задачи на с++ : Сдвинуть элементы на одну позицию...

9
6909 / 5974 / 2709
Регистрация: 14.04.2014
Сообщений: 25,504
18.01.2015, 09:49 2
Считывай построчно, затем каждую строку дели на слова. strtok(), например.
0
0 / 0 / 0
Регистрация: 18.01.2015
Сообщений: 5
18.01.2015, 18:53  [ТС] 3
А если предположить, что одна строка в файле?
Как указывать имя файла, который должен считаться с помощью strtok?
0
6909 / 5974 / 2709
Регистрация: 14.04.2014
Сообщений: 25,504
19.01.2015, 12:10 4
Ну значит, цикл чтения строк один раз выполнится.
strtok() не читает файл. Сначала считываешь строку из файла обычным способом, затем делишь на слова с помощью strtok(). Есть и другие варианты, разумеется.
0
0 / 0 / 0
Регистрация: 18.01.2015
Сообщений: 5
21.01.2015, 14:02  [ТС] 5
Собственно, я создал чудовище. теперь нужна помощь с кодом...
WARNING - код опасен для мозга.
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
nt main()
{
    setlocale(LC_ALL, "Russian");
 
    /*
    ifstream fin;
    fin.open("tfi.txt");
 
    if (!fin.is_open())
    {
    cout << "Такого файла не существует!";
    return -1;
    }
    */
    string sf;
    ifstream fin;
    
 
    fin.open("tfi.txt");
    getline(fin, sf, '\0');
    fin.close();
    cout << sf << endl;
    char word[64];
    while (!fin.eof())
 
    {
        fin >> word;
        cout << word << endl;
    }
 
 
 
    std::string text = sf;
 
    std::stringstream ss(text);
 
    std::string s;
    size_t count = 0;
    for (; ss >> s; count++)
    {
        //  std::cout << s << " : " << s.size() << std::endl;
    }
 
    std::cout << "Total words: " << count << std::endl;
    ofstream fout;
    fout.open("count.txt");
    fout << count;
    fout.close();
    
    
    
    fin.open("count.txt");
    getline(fin, sf, '\0');
    fin.close();
    cout << sf << endl;
 
    
        ofstream fout2;
        fout.open("tfo.txt");
        fout << sf;
        fout.close();
        _getch();
        return 0;
    }


Собственно, что получилось:
Считываю текст из файла. Он считывается по словам и слова подсчитываются. Затем кол-во слов - записывается в файл. Затем считанный текст записывается в файл.
Что должно получиться в итоге:
После считывания, циклический сдвиг букв в словах влево или вправо. И уже этот - новый текст, записывается в новый файл.
На чём застрял:
Для чего был подсчёт слов? Что-бы создать массив с фиксированной величиной. Т.е. чтоб создать cahr a[n], где n -то число из файла (count.txt). Ну и нет предположений, как сделать сдвиг.

Добавлено через 6 часов 22 минуты
Сдвинул символы в словах. В месте с ними сдвигаются и знаки препинания. Это можно исправить с минимальными изменениями в коде?

Новый код:
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
int main()
{
    setlocale(LC_ALL, "Russian");
 
    /*
    ifstream fin;
    fin.open("tfi.txt");
 
    if (!fin.is_open())
    {
    cout << "Такого файла не существует!";
    return -1;
    }
    */
    string sf;
    ifstream fin;
    ofstream fout;
    
 
    fin.open("tfi.txt");
    getline(fin, sf, '\0');
    fin.close();
    cout << sf << endl;
    char word[64];
    char temp[1];
    char word1[64];
    int i;
    while (!fin.eof())
 
    {
        fin >> word;
        cout << word << endl;
    }
 
 
 
    std::string text = sf;
 
    std::stringstream ss(text);
 
    std::string s;
    size_t count = 0;
    for (; ss >> s; count++)
    {
            std::cout << s << " : " << s.size() << std::endl;
            if (s.size() > 1)
            {
                temp[0] = s[s.size() - 1];
                for (i=(s.size() - 2); i >= 0; i--)
                {
                    s[i + 1] = s[i];
                    //std::cout << s[i] << std::endl;
                }
                s[0] = temp[0];
 
            }
            std::cout << s << " : " << s.size() << std::endl;
            ofstream fout;
            fout.open("tfo.txt",ios::app);
            fout << s << " ";
            fout.close();
            
    }
    
    /*
    std::cout << "Total words: " << count << std::endl;
    ofstream fout;
    fout.open("count.txt");
    fout << count;
    fout.close();
    
    
    
    fin.open("count.txt");
    getline(fin, sf, '\0');
    fin.close();
    cout << sf << endl;
 
    */
        
        
        _getch();
        return 0;
    }
0
6909 / 5974 / 2709
Регистрация: 14.04.2014
Сообщений: 25,504
21.01.2015, 14:09 6
Лучший ответ Сообщение было отмечено Cbegginer как решение

Решение

Примерно так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <locale>
#include <vector>
#include <string>
#include <utility>
 
using std::cout;
using std::cin;
using std::endl;
using std::locale;
using std::string;
 
 
int main()
{
    locale::global(locale(""));
 
    std::vector< std::pair<size_t, size_t> > v; // массив пар {индекс первой буквы слова, длина слова}
 
    string d = " .,!?"; // разделители
 
    size_t n = 2; // сдвиг на 2
 
    std::ifstream fin("d:\\tfi.txt");
    std::ofstream fout("d:\\tfo.txt");
 
    string str;
 
    while (!fin.eof())
    {
        getline(fin, str);
        cout << str << endl << endl;
        if (str.length() == 0) continue;
 
        v.clear();
 
        size_t b = 0;
        size_t found = str.find_first_of(d);
        while (found != string::npos)
        {
            if (b < found) v.push_back(std::pair<size_t, size_t>(b, found - b));
            b = found + 1;
            found = str.find_first_of(d, found + 1);
        }
        if (b < str.length()) v.push_back(std::pair<size_t, size_t>(b, str.length() - b));
 
        for (size_t i = 0; i < v.size(); ++i)
        {
            if (v[i].second == 1) continue;
 
            string ss = str.substr(v[i].first, v[i].second);
            for (size_t j = 0; j < n; ++j) // сдвиг вправо на n
            {
                char ch = ss[0];
                ss = ss.substr(1) + ch;
            }
            cout << ss << endl;
            str.replace(v[i].first, v[i].second, ss);
        }
        cout << endl;
        fout << str << endl;
    }
 
 
    cout << endl;
    system("pause");
    return 0;
}
1
Миниатюры
Сдвинуть буквы, в каждом слове, влево или вправо, на n символов  
0 / 0 / 0
Регистрация: 18.01.2015
Сообщений: 5
21.01.2015, 14:15  [ТС] 7
Большое спасибо, сейчас буду сидеть и разбираться что и как тут работает!
0
6909 / 5974 / 2709
Регистрация: 14.04.2014
Сообщений: 25,504
21.01.2015, 14:16 8
Там влево, а не вправо.
1
0 / 0 / 0
Регистрация: 18.01.2015
Сообщений: 5
22.01.2015, 02:31  [ТС] 9
Угу, спасибо. Сейчас буду пробовать чтоб через cin можно было с консоли "n" ввести и выбор между сдвигом вправо и влево.

Добавлено через 12 часов 6 минут
Можно поподробнее, как оно работает?=)
Поправте, если что не так написал.
Кликните здесь для просмотра всего текста
C++
1
if (str.length() == 0) continue; //  Если длинна строки не=0, то дальше. Так?
C++
1
2
size_t b = 0; // это индекс первого элемента т.е. первого слова.
size_t found = str.find_first_of(d); // ищет совпадения с символами разделителями в текущем слове,а текущее слово это b
Ну и вот этот алгоритм распишите пожалуйста, прям по действиям. гуглил каждое слово, но связь так и не уловил. Пока что, члишком сложные конструкции для меня.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
while (found != string::npos)
        {
            if (b < found) v.push_back(std::pair<size_t, size_t>(b, found - b));
            b = found + 1;
            found = str.find_first_of(d, found + 1);
        }
        if (b < str.length()) v.push_back(std::pair<size_t, size_t>(b, str.length() - b));
 
        for (size_t i = 0; i < v.size(); ++i)
        {
            if (v[i].second == 1) continue;
 
            string ss = str.substr(v[i].first, v[i].second);
            for (size_t j = 0; j < n; ++j) // сдвиг вправо на n
            {
                char ch = ss[0];
                ss = ss.substr(1) + ch;
            }
            cout << ss << endl;
            str.replace(v[i].first, v[i].second, ss);
        }
0
6909 / 5974 / 2709
Регистрация: 14.04.2014
Сообщений: 25,504
22.01.2015, 10:45 10
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
if (str.length() == 0) continue; // Это пропуск пустой строки. Ну мало ли что там в файле.
 
size_t b = 0; // для новой строки предполагается, что первое слово начинается с её начала (индекс = 0)
size_t found = str.find_first_of(d); // ищет первый разделитель от начала строки, чтобы определить конец первого слова
 
while (found != string::npos) // пока не закончились разделители
        {
            // добавить данные слова в массив
            // невыполнение условия означает, что есть несколько подряд идущих разделителей, тогда данные слова не добавляются
            if (b < found) v.push_back(std::pair<size_t, size_t>(b, found - b));
            b = found + 1; // сдвинуть начало след. слова за последний найденный разделитель
            found = str.find_first_of(d, found + 1); // найти следующий разделитель
        }
        // добавить при необходимости данные последнего слова (для которого нет конечного разделителя)
        if (b < str.length()) v.push_back(std::pair<size_t, size_t>(b, str.length() - b));
 
        for (size_t i = 0; i < v.size(); ++i) // цикл по найденным позициям слов текущей строки
        {
            if (v[i].second == 1) continue; // пропуск слова, состоящего из одной буквы (сдвигать нечего)
 
            string ss = str.substr(v[i].first, v[i].second); // выделить слово по его данным
            for (size_t j = 0; j < n; ++j) // сдвиг вправо на n, каждая итерация - сдвиг на 1 символ
            {
                char ch = ss[0]; // сохранить символ, который выходит за пределы слова
                ss = ss.substr(1) + ch; // скомпоновать новую строку
            }
            cout << ss << endl; // вывод на экран (для контроля)
            str.replace(v[i].first, v[i].second, ss); // записать модифицированное слово назад в строку, разделители остаются на своих местах
        }
Добавлено через 6 минут
Вообще-то правильнее будет так, чтобы выходной файл также содержал пустые строки:
C++
1
2
3
4
5
if (str.length() == 0)
{
    fout << endl;
    continue;
}
Сдвиг можно проще записать:
C++
1
ss = ss.substr(1) + ss[0];
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
22.01.2015, 10:45

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь.

Циклически сдвинуть элементы массива на K элементов вправо (влево).
1)Дана последовательность чисел, среди которых имеется один нуль. Вывести на печать все числа,...

Сдвинуть элементы в dataGridView Вверх/Вниз/Вправо/Влево
Нужно сдвинуть элементы матрицы(4х4) в dataGridView Вверх/Вниз/Вправо/Влево избавившись от пустых...

Зашифровать строку символов, поменяв в каждом слове первую и вторую буквы
Дана строка символов. Ввод строки заканчивается при вводе символа “F”. Зашифровать строку символов,...

Строки. В каждом чётном по порядку слове удалить все нечётные буквы, а в каждом нечётном слове удалить все чётные буквы.
8.4.1. Помогите, пожалуйста, решить задачу в С++. Дана строка символов, состоящая из русских...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2020, vBulletin Solutions, Inc.