Что корректный путь состоит в том, чтобы объявить и использовать ФАЙЛ * указатель в C/C++?

У меня сейчас нет времени на все объяснения (извините) s>,

Объяснение

Основная проблема здесь заключается в том, что использование $unwind это ваша проблема, и она вам не нужна. Вместо этого используйте $map для содержимого созданного массива, сливающегося с массивом "decks". Тогда вы можете иметь nulls.

Здесь вы хотите получить значения из $lookup из вашей коллекции "tenants" транспонировать в существующий массив в вашей коллекции "beds/bedspaces" для своего собственного существующие значения "tenant", которые являются ссылками ObjectId для зарубежной коллекции.

Этап $lookup не может сделать это, просто назвав путь к полю в выходном сигнале "as", где этот путь уже находится внутри другого массива, и на самом деле в выходных данных $lookup всегда всегда массив результатов, полученных из зарубежной коллекции. Вам нужно единичных значений для каждого фактического соответствия, и, конечно, вы ожидаете, что null будет на месте, где ничего не совпадает, и, конечно, сохраните исходный массив документов "decks" без изменений, но просто включите иностранные детали, где они были найдены.

Ваша попытка кода кажется частично осведомленной об этой точке, поскольку вы используете $unwind для результата $lookup в коллекции ""tenants" в «временный массив» (но вы вставляете в существующий путь, который перезаписывает содержимое), а затем пытаетесь «перегруппировать» как массив через $group и [1153 ] $push . Но проблема, конечно, заключается в том, что результат $lookup не применяется к каждому элементу массива в пределах "decks", поэтому вы получите меньше результатов, чем хотите.

Реальное решение не является «условным $lookup » , но вместо этого транспонирует содержимое «1172]« временного массива » из результата в существующие записи "decks". Вы делаете это, используя $map для обработки элементов массива, и $arrayElemAt вместе с $indexOfArray для возврата соответствующих элементов из [ 1173] «временный массив» путем сопоставления значений _id и "tenant".

          { "$lookup": {
            "from": Tenant.collection.name,
            "let": { "tenant": "$decks.tenant" },
            "pipeline": [
              { "$match": {
                "$expr": { "$in": [ "

У меня сейчас нет времени на все объяснения (извините) s>,

Объяснение

Основная проблема здесь заключается в том, что использование $unwind это ваша проблема, и она вам не нужна. Вместо этого используйте $map для содержимого созданного массива, сливающегося с массивом "decks". Тогда вы можете иметь nulls.

Здесь вы хотите получить значения из $lookup из вашей коллекции "tenants" транспонировать в существующий массив в вашей коллекции "beds/bedspaces" для своего собственного существующие значения "tenant", которые являются ссылками ObjectId для зарубежной коллекции.

Этап $lookup не может сделать это, просто назвав путь к полю в выходном сигнале "as", где этот путь уже находится внутри другого массива, и на самом деле в выходных данных $lookup всегда всегда массив результатов, полученных из зарубежной коллекции. Вам нужно единичных значений для каждого фактического соответствия, и, конечно, вы ожидаете, что null будет на месте, где ничего не совпадает, и, конечно, сохраните исходный массив документов "decks" без изменений, но просто включите иностранные детали, где они были найдены.

Ваша попытка кода кажется частично осведомленной об этой точке, поскольку вы используете $unwind для результата $lookup в коллекции ""tenants" в «временный массив» (но вы вставляете в существующий путь, который перезаписывает содержимое), а затем пытаетесь «перегруппировать» как массив через $group и [1153 ] $push . Но проблема, конечно, заключается в том, что результат $lookup не применяется к каждому элементу массива в пределах "decks", поэтому вы получите меньше результатов, чем хотите.

Реальное решение не является «условным $lookup » , но вместо этого транспонирует содержимое «1172]« временного массива » из результата в существующие записи "decks". Вы делаете это, используя $map для обработки элементов массива, и $arrayElemAt вместе с $indexOfArray для возврата соответствующих элементов из [ 1173] «временный массив» путем сопоставления значений _id и "tenant".

[110]

Отметив, что мы используем $mergeObjects внутри $map , чтобы сохранить существующее содержимое массива "decks" и заменять только (или " merge ") перезаписанное представление "tenant" для каждого члена массива. Вы уже используете выразительный $lookup , и это подобно $mergeObjects является функцией MongoDB 3.6.

Просто для интереса то же самое можно сделать, просто указав каждое поле в массиве. то есть:

            "decks": {
              "$map": {
                "input": "$decks",
                 "in": {
                   "_id": "$this._id",
                   "number": "$this.number",
                   "tenant": {
                     // same expression
                   },
                   "__v": "$this.__v"     // just because it's mongoose
                 }
               }
             }

То же самое можно сказать и о $REMOVE, используемом в $addFields , который также является другой особенностью MongoDB 3.6. Вы можете поочередно просто использовать $project и просто опускать ненужные поля:

{ "$project": {
  "number": "$number",
  "decks": {
    "$map": { /* same expression */ }
  },
  "__v": "

У меня сейчас нет времени на все объяснения (извините) s>,

Объяснение

Основная проблема здесь заключается в том, что использование $unwind это ваша проблема, и она вам не нужна. Вместо этого используйте $map для содержимого созданного массива, сливающегося с массивом "decks". Тогда вы можете иметь nulls.

Здесь вы хотите получить значения из $lookup из вашей коллекции "tenants" транспонировать в существующий массив в вашей коллекции "beds/bedspaces" для своего собственного существующие значения "tenant", которые являются ссылками ObjectId для зарубежной коллекции.

Этап $lookup не может сделать это, просто назвав путь к полю в выходном сигнале "as", где этот путь уже находится внутри другого массива, и на самом деле в выходных данных $lookup всегда всегда массив результатов, полученных из зарубежной коллекции. Вам нужно единичных значений для каждого фактического соответствия, и, конечно, вы ожидаете, что null будет на месте, где ничего не совпадает, и, конечно, сохраните исходный массив документов "decks" без изменений, но просто включите иностранные детали, где они были найдены.

Ваша попытка кода кажется частично осведомленной об этой точке, поскольку вы используете $unwind для результата $lookup в коллекции ""tenants" в «временный массив» (но вы вставляете в существующий путь, который перезаписывает содержимое), а затем пытаетесь «перегруппировать» как массив через $group и [1153 ] $push . Но проблема, конечно, заключается в том, что результат $lookup не применяется к каждому элементу массива в пределах "decks", поэтому вы получите меньше результатов, чем хотите.

Реальное решение не является «условным $lookup » , но вместо этого транспонирует содержимое «1172]« временного массива » из результата в существующие записи "decks". Вы делаете это, используя $map для обработки элементов массива, и $arrayElemAt вместе с $indexOfArray для возврата соответствующих элементов из [ 1173] «временный массив» путем сопоставления значений _id и "tenant".

[110]

Отметив, что мы используем $mergeObjects внутри $map , чтобы сохранить существующее содержимое массива "decks" и заменять только (или " merge ") перезаписанное представление "tenant" для каждого члена массива. Вы уже используете выразительный $lookup , и это подобно $mergeObjects является функцией MongoDB 3.6.

Просто для интереса то же самое можно сделать, просто указав каждое поле в массиве. то есть:

[111]

То же самое можно сказать и о $REMOVE, используемом в $addFields , который также является другой особенностью MongoDB 3.6. Вы можете поочередно просто использовать $project и просто опускать ненужные поля:

[112]

Но в основном это работает. Взяв результат $lookup и затем перенес эти результаты обратно в исходный массив в документе.

Пример списка

Также абстрагируясь от ваших данных из предыдущих вопросов здесь, что немного лучше, чем то, что вы опубликовали в вопросе здесь. Список для запуска для демонстрации:

const { Schema, Types: { ObjectId } } = mongoose = require('mongoose');

const uri = 'mongodb://localhost:27017/hotel';
const opts = { useNewUrlParser: true };

mongoose.set('useFindAndModify', false);
mongoose.set('useCreateIndexes', true);
mongoose.set('debug', true);

const tenantSchema = new Schema({
  name: String,
  age: Number
});

const deckSchema = new Schema({
  number: Number,
  tenant: { type: Schema.Types.ObjectId, ref: 'Tenant' }
});

const bedSchema = new Schema({
  number: Number,
  decks: [deckSchema]
});

const roomSchema = new Schema({
  bedspaces: [{ type: Schema.Types.ObjectId, ref: 'Bed' }]
});


const Tenant = mongoose.model('Tenant', tenantSchema);
const Bed = mongoose.model('Bed', bedSchema);
const Room = mongoose.model('Room', roomSchema);

const log = data => console.log(JSON.stringify(data, undefined, 2));

(async function() {

  try {

    const conn = await mongoose.connect(uri, opts);

    // Clean data
    await Promise.all(
      Object.entries(conn.models).map(([k, m]) => m.deleteMany())
    );

    // Insert data
    let [john, jane, bilbo ] = await Tenant.insertMany([
      {
        _id: ObjectId("5c964ae7f5097e3020d1926c"),
        name: "john doe",
        age: 11
      },
      {
        _id: ObjectId("5c964b2531bc162fdce64f15"),
        name: "jane doe",
        age: 12
      },
      {
        _id: ObjectId("5caa5454494558d863513b24"),
        name: "bilbo",
        age: 111
      }
    ]);

    let bedspaces = await Bed.insertMany([
      {
        _id: ObjectId("5c98d89c6bd5fc26a4c2851b"),
        number: 1,
        decks: [
          {
            number: 1,
            tenant: john
          },
          {
            number: 1,
            tenant: jane
          }
        ]
      },
      {
        _id: ObjectId("5c98d89f6bd5fc26a4c28522"),
        number: 2,
        decks: [
          {
            number: 2,
            tenant: bilbo
          },
          {
            number: 3
          }
        ]
      }
    ]);

    await Room.create({ bedspaces });

    // Aggregate

    let results = await Room.aggregate([
      { "$lookup": {
        "from": Bed.collection.name,
        "let": { "bedspaces": "$bedspaces" },
        "pipeline": [
          { "$match": {
            "$expr": { "$in": [ "

У меня сейчас нет времени на все объяснения (извините) s>,

Объяснение

Основная проблема здесь заключается в том, что использование $unwind это ваша проблема, и она вам не нужна. Вместо этого используйте $map для содержимого созданного массива, сливающегося с массивом "decks". Тогда вы можете иметь nulls.

Здесь вы хотите получить значения из $lookup из вашей коллекции "tenants" транспонировать в существующий массив в вашей коллекции "beds/bedspaces" для своего собственного существующие значения "tenant", которые являются ссылками ObjectId для зарубежной коллекции.

Этап $lookup не может сделать это, просто назвав путь к полю в выходном сигнале "as", где этот путь уже находится внутри другого массива, и на самом деле в выходных данных $lookup всегда всегда массив результатов, полученных из зарубежной коллекции. Вам нужно единичных значений для каждого фактического соответствия, и, конечно, вы ожидаете, что null будет на месте, где ничего не совпадает, и, конечно, сохраните исходный массив документов "decks" без изменений, но просто включите иностранные детали, где они были найдены.

Ваша попытка кода кажется частично осведомленной об этой точке, поскольку вы используете $unwind для результата $lookup в коллекции ""tenants" в «временный массив» (но вы вставляете в существующий путь, который перезаписывает содержимое), а затем пытаетесь «перегруппировать» как массив через $group и [1153 ] $push . Но проблема, конечно, заключается в том, что результат $lookup не применяется к каждому элементу массива в пределах "decks", поэтому вы получите меньше результатов, чем хотите.

Реальное решение не является «условным $lookup » , но вместо этого транспонирует содержимое «1172]« временного массива » из результата в существующие записи "decks". Вы делаете это, используя $map для обработки элементов массива, и $arrayElemAt вместе с $indexOfArray для возврата соответствующих элементов из [ 1173] «временный массив» путем сопоставления значений _id и "tenant".

[110]

Отметив, что мы используем $mergeObjects внутри $map , чтобы сохранить существующее содержимое массива "decks" и заменять только (или " merge ") перезаписанное представление "tenant" для каждого члена массива. Вы уже используете выразительный $lookup , и это подобно $mergeObjects является функцией MongoDB 3.6.

Просто для интереса то же самое можно сделать, просто указав каждое поле в массиве. то есть:

[111]

То же самое можно сказать и о $REMOVE, используемом в $addFields , который также является другой особенностью MongoDB 3.6. Вы можете поочередно просто использовать $project и просто опускать ненужные поля:

[112]

Но в основном это работает. Взяв результат $lookup и затем перенес эти результаты обратно в исходный массив в документе.

Пример списка

Также абстрагируясь от ваших данных из предыдущих вопросов здесь, что немного лучше, чем то, что вы опубликовали в вопросе здесь. Список для запуска для демонстрации:

[113]

Возвращает:

Mongoose: tenants.deleteMany({}, {})
Mongoose: beds.deleteMany({}, {})
Mongoose: rooms.deleteMany({}, {})
Mongoose: tenants.insertMany([ { _id: 5c964ae7f5097e3020d1926c, name: 'john doe', age: 11, __v: 0 }, { _id: 5c964b2531bc162fdce64f15, name: 'jane doe', age: 12, __v: 0 }, { _id: 5caa5454494558d863513b24, name: 'bilbo', age: 111, __v: 0 } ], {})
Mongoose: beds.insertMany([ { _id: 5c98d89c6bd5fc26a4c2851b, number: 1, decks: [ { _id: 5caa5af6ed3dce1c3ed72cef, number: 1, tenant: 5c964ae7f5097e3020d1926c }, { _id: 5caa5af6ed3dce1c3ed72cee, number: 1, tenant: 5c964b2531bc162fdce64f15 } ], __v: 0 }, { _id: 5c98d89f6bd5fc26a4c28522, number: 2, decks: [ { _id: 5caa5af6ed3dce1c3ed72cf2, number: 2, tenant: 5caa5454494558d863513b24 }, { _id: 5caa5af6ed3dce1c3ed72cf1, number: 3 } ], __v: 0 } ], {})
Mongoose: rooms.insertOne({ bedspaces: [ ObjectId("5c98d89c6bd5fc26a4c2851b"), ObjectId("5c98d89f6bd5fc26a4c28522") ], _id: ObjectId("5caa5af6ed3dce1c3ed72cf3"), __v: 0 })
Mongoose: rooms.aggregate([ { '$lookup': { from: 'beds', let: { bedspaces: '$bedspaces' }, pipeline: [ { '$match': { '$expr': { '$in': [ '

У меня сейчас нет времени на все объяснения (извините) s>,

Объяснение

Основная проблема здесь заключается в том, что использование $unwind это ваша проблема, и она вам не нужна. Вместо этого используйте $map для содержимого созданного массива, сливающегося с массивом "decks". Тогда вы можете иметь nulls.

Здесь вы хотите получить значения из $lookup из вашей коллекции "tenants" транспонировать в существующий массив в вашей коллекции "beds/bedspaces" для своего собственного существующие значения "tenant", которые являются ссылками ObjectId для зарубежной коллекции.

Этап $lookup не может сделать это, просто назвав путь к полю в выходном сигнале "as", где этот путь уже находится внутри другого массива, и на самом деле в выходных данных $lookup всегда всегда массив результатов, полученных из зарубежной коллекции. Вам нужно единичных значений для каждого фактического соответствия, и, конечно, вы ожидаете, что null будет на месте, где ничего не совпадает, и, конечно, сохраните исходный массив документов "decks" без изменений, но просто включите иностранные детали, где они были найдены.

Ваша попытка кода кажется частично осведомленной об этой точке, поскольку вы используете $unwind для результата $lookup в коллекции ""tenants" в «временный массив» (но вы вставляете в существующий путь, который перезаписывает содержимое), а затем пытаетесь «перегруппировать» как массив через $group и [1153 ] $push . Но проблема, конечно, заключается в том, что результат $lookup не применяется к каждому элементу массива в пределах "decks", поэтому вы получите меньше результатов, чем хотите.

Реальное решение не является «условным $lookup » , но вместо этого транспонирует содержимое «1172]« временного массива » из результата в существующие записи "decks". Вы делаете это, используя $map для обработки элементов массива, и $arrayElemAt вместе с $indexOfArray для возврата соответствующих элементов из [ 1173] «временный массив» путем сопоставления значений _id и "tenant".

[110]

Отметив, что мы используем $mergeObjects внутри $map , чтобы сохранить существующее содержимое массива "decks" и заменять только (или " merge ") перезаписанное представление "tenant" для каждого члена массива. Вы уже используете выразительный $lookup , и это подобно $mergeObjects является функцией MongoDB 3.6.

Просто для интереса то же самое можно сделать, просто указав каждое поле в массиве. то есть:

[111]

То же самое можно сказать и о $REMOVE, используемом в $addFields , который также является другой особенностью MongoDB 3.6. Вы можете поочередно просто использовать $project и просто опускать ненужные поля:

[112]

Но в основном это работает. Взяв результат $lookup и затем перенес эти результаты обратно в исходный массив в документе.

Пример списка

Также абстрагируясь от ваших данных из предыдущих вопросов здесь, что немного лучше, чем то, что вы опубликовали в вопросе здесь. Список для запуска для демонстрации:

[113]

Возвращает:

[114]

Показывает null для второй записи второй записи в массиве bedspaces, как и ожидалось.

id', '$bedspaces' ] } } }, { '$lookup': { from: 'tenants', let: { tenant: '$decks.tenant' }, pipeline: [ { '$match': { '$expr': { '$in': [ '

У меня сейчас нет времени на все объяснения (извините) s>,

Объяснение

Основная проблема здесь заключается в том, что использование $unwind это ваша проблема, и она вам не нужна. Вместо этого используйте $map для содержимого созданного массива, сливающегося с массивом "decks". Тогда вы можете иметь nulls.

Здесь вы хотите получить значения из $lookup из вашей коллекции "tenants" транспонировать в существующий массив в вашей коллекции "beds/bedspaces" для своего собственного существующие значения "tenant", которые являются ссылками ObjectId для зарубежной коллекции.

Этап $lookup не может сделать это, просто назвав путь к полю в выходном сигнале "as", где этот путь уже находится внутри другого массива, и на самом деле в выходных данных $lookup всегда всегда массив результатов, полученных из зарубежной коллекции. Вам нужно единичных значений для каждого фактического соответствия, и, конечно, вы ожидаете, что null будет на месте, где ничего не совпадает, и, конечно, сохраните исходный массив документов "decks" без изменений, но просто включите иностранные детали, где они были найдены.

Ваша попытка кода кажется частично осведомленной об этой точке, поскольку вы используете $unwind для результата $lookup в коллекции ""tenants" в «временный массив» (но вы вставляете в существующий путь, который перезаписывает содержимое), а затем пытаетесь «перегруппировать» как массив через $group и [1153 ] $push . Но проблема, конечно, заключается в том, что результат $lookup не применяется к каждому элементу массива в пределах "decks", поэтому вы получите меньше результатов, чем хотите.

Реальное решение не является «условным $lookup » , но вместо этого транспонирует содержимое «1172]« временного массива » из результата в существующие записи "decks". Вы делаете это, используя $map для обработки элементов массива, и $arrayElemAt вместе с $indexOfArray для возврата соответствующих элементов из [ 1173] «временный массив» путем сопоставления значений _id и "tenant".

[110]

Отметив, что мы используем $mergeObjects внутри $map , чтобы сохранить существующее содержимое массива "decks" и заменять только (или " merge ") перезаписанное представление "tenant" для каждого члена массива. Вы уже используете выразительный $lookup , и это подобно $mergeObjects является функцией MongoDB 3.6.

Просто для интереса то же самое можно сделать, просто указав каждое поле в массиве. то есть:

[111]

То же самое можно сказать и о $REMOVE, используемом в $addFields , который также является другой особенностью MongoDB 3.6. Вы можете поочередно просто использовать $project и просто опускать ненужные поля:

[112]

Но в основном это работает. Взяв результат $lookup и затем перенес эти результаты обратно в исходный массив в документе.

Пример списка

Также абстрагируясь от ваших данных из предыдущих вопросов здесь, что немного лучше, чем то, что вы опубликовали в вопросе здесь. Список для запуска для демонстрации:

[113]

Возвращает:

[114]

Показывает null для второй записи второй записи в массиве bedspaces, как и ожидалось.

id', '$tenant' ] } } } ], as: 'tenant' } }, { '$addFields': { decks: { '$map': { input: '$decks', in: { '$mergeObjects': [ '$this', { tenant: [Object] } ] } } }, tenant: '$REMOVE' } } ], as: 'bedspaces' } } ], {}) [ { "_id": "5caa5af6ed3dce1c3ed72cf3", "bedspaces": [ { "_id": "5c98d89c6bd5fc26a4c2851b", "number": 1, "decks": [ { "_id": "5caa5af6ed3dce1c3ed72cef", "number": 1, "tenant": { "_id": "5c964ae7f5097e3020d1926c", "name": "john doe", "age": 11, "__v": 0 } }, { "_id": "5caa5af6ed3dce1c3ed72cee", "number": 1, "tenant": { "_id": "5c964b2531bc162fdce64f15", "name": "jane doe", "age": 12, "__v": 0 } } ], "__v": 0 }, { "_id": "5c98d89f6bd5fc26a4c28522", "number": 2, "decks": [ { "_id": "5caa5af6ed3dce1c3ed72cf2", "number": 2, "tenant": { "_id": "5caa5454494558d863513b24", "name": "bilbo", "age": 111, "__v": 0 } }, { "_id": "5caa5af6ed3dce1c3ed72cf1", "number": 3, "tenant": null } ], "__v": 0 } ], "__v": 0 } ]

Показывает null для второй записи второй записи в массиве bedspaces, как и ожидалось.

id", "$bedspaces" ] } }}, { "$lookup": { "from": Tenant.collection.name, "let": { "tenant": "$decks.tenant" }, "pipeline": [ { "$match": { "$expr": { "$in": [ "

У меня сейчас нет времени на все объяснения (извините) s>,

Объяснение

Основная проблема здесь заключается в том, что использование $unwind это ваша проблема, и она вам не нужна. Вместо этого используйте $map для содержимого созданного массива, сливающегося с массивом "decks". Тогда вы можете иметь nulls.

Здесь вы хотите получить значения из $lookup из вашей коллекции "tenants" транспонировать в существующий массив в вашей коллекции "beds/bedspaces" для своего собственного существующие значения "tenant", которые являются ссылками ObjectId для зарубежной коллекции.

Этап $lookup не может сделать это, просто назвав путь к полю в выходном сигнале "as", где этот путь уже находится внутри другого массива, и на самом деле в выходных данных $lookup всегда всегда массив результатов, полученных из зарубежной коллекции. Вам нужно единичных значений для каждого фактического соответствия, и, конечно, вы ожидаете, что null будет на месте, где ничего не совпадает, и, конечно, сохраните исходный массив документов "decks" без изменений, но просто включите иностранные детали, где они были найдены.

Ваша попытка кода кажется частично осведомленной об этой точке, поскольку вы используете $unwind для результата $lookup в коллекции ""tenants" в «временный массив» (но вы вставляете в существующий путь, который перезаписывает содержимое), а затем пытаетесь «перегруппировать» как массив через $group и [1153 ] $push . Но проблема, конечно, заключается в том, что результат $lookup не применяется к каждому элементу массива в пределах "decks", поэтому вы получите меньше результатов, чем хотите.

Реальное решение не является «условным $lookup » , но вместо этого транспонирует содержимое «1172]« временного массива » из результата в существующие записи "decks". Вы делаете это, используя $map для обработки элементов массива, и $arrayElemAt вместе с $indexOfArray для возврата соответствующих элементов из [ 1173] «временный массив» путем сопоставления значений _id и "tenant".

[110]

Отметив, что

8
задан Jonathan Leffler 26 February 2009 в 07:32
поделиться

5 ответов

Не имеет значения вообще, локально ли это или глобально. Объем указателя файла не имеет никакого отношения к своему использованию.

В целом это - хорошая идея избежать глобальных переменных как можно больше.

Вот образец, показывающий, как скопировать с input.txt кому: output.txt:

#include <stdio.h>
int main(void) {
    FILE *fin, *fout; int c;

    // Open both files, fail fast if either no good.

    if ((fin = fopen("input.txt", "r")) == NULL) {
        fprintf(stderr, "Cannot read from input.txt");
        return 1;
    }

    if ((fout = fopen("output.txt", "w")) == NULL) {
        fprintf(stderr, "Cannot write to output.txt");
        fclose(fin);
        return 1;
    }

    // Transfer character by character.

    while ((c = fgetc(fin)) >= 0) {
        fputc (c, fout);
    }

    // Close both files and exit.

    fclose(fin);
    fclose(fout);

    return 0;
}
18
ответ дан 5 December 2019 в 06:54
поделиться

Это - просто обычный указатель как любой другой.

FILE *CreateLogFile() 
{
    return fopen("logfile.txt","w"); // allocates a FILE object and returns a pointer to it
}

void UsefulFunction()
{
   FILE *pLog = CreateLogFile(); // it's safe to return a pointer from a func
   int resultsOfWork = DoSomeWork();
   fprintf( pLog, "Work did %d\n", resultsOfWork );  // you can pass it to other functions
   fclose( pLog ); // just be sure to clean it up when you are done with fclose()
   pLog = NULL;    // and it's a good idea to overwrite the pointer afterwards
                   // so it's obvious you deleted what it points to
}
4
ответ дан 5 December 2019 в 06:54
поделиться

Вот первый хит на Google для "файла io в c"

http://www.cs.bu.edu/teaching/c/file-io/intro/

Вот третий хит из gamedev с большим количеством наклона C++

http://www.gamedev.net/reference/articles/article1127.asp

Вы объявляете указатель в объеме, что Вам нужен он.

1
ответ дан 5 December 2019 в 06:54
поделиться
int main(void)
{
  char c;
  FILE *read;
  read = fopen("myfile", "r"); // opens "myfile" for reading
  if(read == NULL)
  {
    perror("Error: could not open \"myfile\" for reading.\n");
    exit(1);
  }
  c = fgetc(read);
  fclose(read);
  printf("The first character of myfile is %c.\n", c);
  return 0;
}

Вам отлично разрешают объявить глобальные дескрипторы файлов, если Вам нравится, точно так же, как какая-либо другая переменная, но она не может быть рекомендована.

Это - путь C. C++ может использовать это, но я думаю, что существует больше C++ дружественный способ сделать его. Как примечание, я ненавижу его, когда вопросами является отмеченный C/C++, потому что C и C++ не являются тем же языком и не работают то же. C++ имеет много различных способов сделать вещи, которые не имеет C, и они могут быть легче для Вас сделать в контексте C++, но не являются допустимым C. Таким образом, в то время как это будет работать на любой язык, это не то, что Вы хотите при преобладающем использовании C++.

Править: Добавленный некоторая проверка ошибок. Всегда используйте проверку ошибок в своем коде.

1
ответ дан 5 December 2019 в 06:54
поделиться

Во-первых, имейте в виду, что указатель файла (и связанная выделенная структура) основан на более низком открытом уровне () чтение () запись () вызовы. Связанный дескриптор файла (полученный fileno (file_pointer) является наименее интересной вещью, но что-то Вы могли бы хотеть наблюдать свой объем с.

Если Ваша попытка объявить указатель файла как глобальный в модуле, обычно очень хорошая идея сохранить это статичным (содержавший в том модуле / объектный файл). Иногда это немного легче, чем хранение его в структуре, которая передается от функции до функции, если необходимо записать что-то второпях.

Например, (плохо)

#include <stdio.h>
#include ...

#define MY_LOG_FILE "file.txt"

FILE *logfile

Лучше сделанный как:

#include <stdio.h>

#define MY_LOG_FILE "file.txt"

static FILE *logfile;

int main(void)
{

ЕСЛИ, Вам не нужны несколько модулей, чтобы иметь доступ к тому указателю, в этом случае Вы - более обеспеченное помещение его в структуре, которая может быть роздана.

Если его необходимое только в одном модуле, рассмотрите объявление его в основном () и разрешение другим функциям принять указатель файла как аргумент. Так, если Ваши функции в модуле не имеют столько аргументов, что другой был бы невыносим.. нет (обычно) никакой причины объявить указатель файла глобально.

Некоторые регистрирующиеся библиотеки делают это, о котором я не забочусь... особенно при контакте с повторно используемыми функциями. Монолитное пространство имен Nevermind C :)

0
ответ дан 5 December 2019 в 06:54
поделиться